日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

单列索引和联合索引,有什么区别?

發布時間:2025/3/21 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 单列索引和联合索引,有什么区别? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

作者:深寒丶

來源:blog.csdn.net/abysscarry/article/details/80792876

背景:

為了提高數據庫效率,建索引是家常便飯;那么當查詢條件為 2 個及以上時,我們是創建多個單列索引還是創建一個聯合索引好呢?他們之間的區別是什么?哪個效率高呢?我在這里詳細測試分析下。

一、聯合索引測試

注:Mysql 版本為 5.7.20

創建測試表(表記錄數為 63188):

CREATE TABLE `t_mobilesms_11` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`userId` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT '用戶id,創建任務時的userid',`mobile` varchar(24) NOT NULL DEFAULT '' COMMENT '手機號碼',`billMonth` varchar(32) DEFAULT NULL COMMENT '賬單月',`time` varchar(32) DEFAULT NULL COMMENT '收/發短信時間',`peerNumber` varchar(64) NOT NULL COMMENT '對方號碼',`location` varchar(64) DEFAULT NULL COMMENT '通信地(自己的)',`sendType` varchar(16) DEFAULT NULL COMMENT 'SEND-發送; RECEIVE-收取',`msgType` varchar(8) DEFAULT NULL COMMENT 'SMS-短信; MSS-彩信',`serviceName` varchar(256) DEFAULT NULL COMMENT '業務名稱. e.g. 點對點(網內)',`fee` int(11) DEFAULT NULL COMMENT '通信費(單位分)',`createTime` datetime DEFAULT NULL COMMENT '創建時間',`lastModifyTime` datetime DEFAULT NULL COMMENT '最后修改時間',PRIMARY KEY (`id`),KEY `聯合索引` (`userId`,`mobile`,`billMonth`) ) ENGINE=InnoDB AUTO_INCREMENT=71185 DEFAULT CHARSET=utf8 COMMENT='手機短信詳情'

我們為userId,?mobile,?billMonth三個字段添加上聯合索引!

我們選擇?explain?查看執行計劃來觀察索引利用情況:

1.查詢條件為?userid

EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE userid='2222'

可以通過key看到,聯合索引有效

2.查詢條件為?mobile

EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE mobile='13281899972'

可以看到聯合索引無效

3.查詢條件為?billMonth

EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE billMonth='2018-04'

聯合索引無效

4.查詢條件為?userid and mobile

EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE userid='2222' AND mobile='13281899972'

聯合索引有效

5.查詢條件為?mobile and userid

EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE mobile='13281899972' AND userid='2222'

在 4 的基礎上調換了查詢條件的順序,發現聯合索引依舊有效

6.查詢條件為?userid or mobile

EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE userid='2222' OR mobile='13281899972'

把?and?換成?or,發現聯合所索引無效

7.查詢條件為?userid and billMonth

EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE userid='2222' AND billMonth='2018-04'

這兩個條件分別位于聯合索引位置的第一和第三,測試聯合索引依舊有效

8.查詢條件為?mobile and billMonth

EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE mobile='13281899972' AND billMonth='2018-04'

這兩個條件分別位于聯合索引位置的第二和第三,發現聯合索引無效

9.查詢條件為?userid and mobile and billMonth

EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE userid='2222' AND mobile='13281899972' AND billMonth='2018-04'

所有條件一起查詢,聯合索引有效!(當然,這才是最正統的用法啊!)

二、單列索引測試

創建三個單列索引:

1.查詢條件為?userid and mobile and billMonth

EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE userid='2222' AND mobile='13281899972' AND billMonth='2018-04'

我們發現三個單列索引只有?userid?有效(位置為查詢條件第一個),其他兩個都沒有用上。

那么為什么沒有用上呢?按照我們的理解,三個字段都加索引了,無論怎么排列組合查詢,應該都能利用到這三個索引才對!

其實這里其實涉及到了 mysql 優化器的優化策略!當多條件聯合查詢時,優化器會評估用哪個條件的索引效率最高!它會選擇最佳的索引去使用,也就是說,此處userid 、mobile 、billMonth這三個索引列都能用,只不過優化器判斷只需要使用userid這一個索引就能完成本次查詢,故最終 explain 展示的 key 為 userid。

當然,如果優化器判斷本次查詢非要全使用三個索引才能效率最高,那么 explain 的 key 就會是userid 、mobile 、billMonth,都會生效!

2.查詢條件為?mobile and billMonth

EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE mobile='13281899972' AND billMonth='2018-04'

我們發現此處兩個查詢條件只有?mobile?生效(位置也為查詢條件第一個)

3.查詢條件為?userid or mobile

EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE userid='2222' OR mobile='13281899972'

這次把?and?換成?or,發現兩個查詢條件都用上索引了!

我們在網上可能常常看到有人說 or 會導致索引失效,其實這并不準確。而且我們首先需要判斷用的是哪個數據庫哪個版本,什么引擎?

比如我用的是 mysql5.7 版本,innodb 引擎,在這個環境下我們再去討論索引的具體問題。

關于 or 查詢的真相是:

所謂的索引失效指的是:假如 or 連接的倆個查詢條件字段中有一個沒有索引的話,引擎會放棄索引而產生全表掃描。我們從 or 的基本含義出發應該能理解并認可這種說法,沒啥問題。

此刻需要注意type類型為index_merge。

我查資料說 mysql 5.0 版本之前 使用 or只會用到一個索引(即使如上我給 userid 和 mobile 都建立的單列索引),但自從 5.0 版本開始引入了index_merge 索引合并優化!也就是說,我們現在可以利用上多個索引去優化 or 查詢了。

index_merge 作用:

1、索引合并是把幾個索引的范圍掃描合并成一個索引。

2、索引合并的時候,會對索引進行并集,交集或者先交集再并集操作,以便合并成一個索引。

3、這些需要合并的索引只能是一個表的。不能對多表進行索引合并。

index_merge 應用場景:

1.對 OR 語句求并集,如查詢SELECT * FROM TB1 WHERE c1="xxx" OR c2=""xxx"時,如果 c1 和 c2 列上分別有索引,可以按照 c1 和 c2 條件進行查詢,再將查詢結果合并(union)操作,得到最終結果

2.對 AND 語句求交集,如查詢SELECT * FROM TB1 WHERE c1="xxx" AND c2=""xxx"時,如果 c1 和 c2 列上分別有索引,可以按照 c1 和 c2 條件進行查詢,再將查詢結果取交集(intersect)操作,得到最終結果

3.對 AND 和 OR 組合語句求結果

三、結論

通俗理解:

利用索引中的附加列,您可以縮小搜索的范圍,但使用一個具有兩列的索引 不同于使用兩個單獨的索引。復合索引的結構與電話簿類似,人名由姓和名構成,電話簿首先按姓氏對進行排序,然后按名字對有相同姓氏的人進行排序。如果您知道姓,電話簿將非常有用;如果您知道姓和名,電話簿則更為有用,但如果您只知道名不姓,電話簿將沒有用處

所以說創建復合索引時,應該仔細考慮列的順序。對索引中的所有列執行搜索或僅對前幾列執行搜索時,復合索引非常有用僅對后面的任意列執行搜索時,復合索引則沒有用處。

重點:

多個單列索引多條件查詢時優化器會選擇最優索引策略可能只用一個索引,也可能將多個索引全用上!?但多個單列索引底層會建立多個 B+索引樹,比較占用空間,也會浪費一定搜索效率,故如果只有多條件聯合查詢時最好建聯合索引!

最左前綴原則:

顧名思義是最左優先,以最左邊的為起點任何連續的索引都能匹配上, 注:如果第一個字段是范圍查詢需要單獨建一個索引注:在創建聯合索引時,要根據業務需求,where 子句中使用最頻繁的一列放在最左邊。這樣的話擴展性較好,比如?userid?經常需要作為查詢條件,而?mobile?不常常用,則需要把?userid?放在聯合索引的第一位置,即最左邊

同時存在聯合索引和單列索引(字段有重復的),這個時候查詢 mysql 會怎么用索引呢?

這個涉及到 mysql 本身的查詢優化器策略了,當一個表有多條索引可走時, Mysql 根據查詢語句的成本來選擇走哪條索引;

有人說 where 查詢是按照從左到右的順序,所以篩選力度大的條件盡量放前面。網上百度過,很多都是這種說法,但是據我研究,mysql 執行優化器會對其進行優化當不考慮索引時,where 條件順序對效率沒有影響真正有影響的是是否用到了索引

聯合索引本質:

當創建**(a,b,c)聯合索引時,相當于創建了(a)單列索引**,(a,b)聯合索引以及**(a,b,c)聯合索引** 想要索引生效的話,只能使用 a 和 a,b 和 a,b,c 三種組合;當然,我們上面測試過,a,c 組合也可以,但實際上只用到了 a 的索引,c 并沒有用到!注:這個可以結合上邊的 通俗理解 來思考!

其他知識點:

1、需要加索引的字段,要在 where 條件中

2、數據量少的字段不需要加索引;因為建索引有一定開銷,如果數據量小則沒必要建索引(速度反而慢)

3、避免在 where 子句中使用or來連接條件,因為如果倆個字段中有一個沒有索引的話,引擎會放棄索引而產生全表掃描

4、聯合索引比對每個列分別建索引更有優勢,因為索引建立得越多就越占磁盤空間,在更新數據的時候速度會更慢。另外建立多列索引時,順序也是需要注意的,應該將嚴格的索引放在前面,這樣篩選的力度會更大,效率更高

最后的說明:

網上關于索引優化等文章太多了,針對各個數據庫各個版本各種引擎都可能存在不一樣的說法

我們的 SQL 引擎自帶的優化也越來越強大,說不定你的某個 SQL 優化認知,其 SQL 引擎在某次升級中早就自優化了。

所以要么跟進官方文檔,要么關注數據庫大牛的最新文章,要么在現有數據庫環境下自己去親手測試!

總結

以上是生活随笔為你收集整理的单列索引和联合索引,有什么区别?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲天堂区 | 中文字幕高清在线观看 | 美女丝袜合集 | 精品国产av色一区二区深夜久久 | 久久aⅴ乱码一区二区三区 亚洲成人18 | 免费看日韩| 亚洲v在线观看 | 欧美另类在线播放 | 一区二区久久久 | 四季av国产一区二区三区 | 老女人性生活视频 | 国产丰满大乳奶水在线视频 | 日韩激情在线播放 | 北条麻妃一区二区三区四区五区 | 亚洲永久免费网站 | 日韩av看片 | 国产精品福利网站 | 18黄暴禁片在线观看 | 蜜桃视频在线观看www | 国产99久久久欧美黑人 | 亚洲综合一二三 | 九热精品 | av中字 | 不卡在线一区 | www.黄色一片 | 5个黑人躁我一个视频 | 黄色一级免费 | 成人毛片基地 | 日韩国产成人在线 | 日韩av在线天堂 | 国产免费无码一区二区 | 天堂俺去俺来也www久久婷婷 | 麻豆一区二区三区精品视频 | 人与禽一级全黄 | 老色批永久免费网站www | 色黄视频| 春色av | 成人免费在线观看 | 欧美精品在线一区二区 | 在线午夜视频 | 欧洲中文字幕日韩精品成人 | 日本黄网在线观看 | 黄色大片久久 | 精品熟妇视频一区二区三区 | 欧美肥老妇视频 | 午夜一本 | 中文字幕视频免费 | av av在线| 国产高清一级片 | 欧美亚洲视频在线观看 | www.在线观看av | 91福利小视频 | 五月深爱网 | 激情播播网 | 爱豆国产剧免费观看大全剧集 | 毛片成人网 | 欧洲亚洲综合 | 欧美永久视频 | 女同毛片一区二区三区 | 北条麻妃av在线播放 | 殴美黄色大片 | 美国一级黄色大片 | 欧洲自拍一区 | 日韩少妇内射免费播放18禁裸乳 | 91成人在线观看喷潮蘑菇 | 欧美性猛交ⅹxxx乱大交3 | 二级黄色片| av资源站| 欧美大片免费在线观看 | 国产高清在线视频观看 | 在线成人国产 | 国产成人超碰人人澡人人澡 | 日本护士做爰视频 | 一区二区三区国产 | 一级 黄 色 片69 | 男人操女人免费网站 | www.国产区| 视频1区2区| 91国产视频在线播放 | 亚洲人成免费 | www.色婷婷 | 国产日日干 | 免费看日批视频 | 伊人网在线观看 | 亚洲第一香蕉网 | 色呦呦一区二区 | 伦理片一区二区 | 国产男女猛烈无遮挡免费视频 | 麻豆蜜桃在线观看 | 青青草原综合网 | 亚洲国产精品女人 | 欧美xxxx888| 2019天天操 | 免费毛片小视频 | 国产精品二区一区 | 欧美中文字幕视频 | 91老师片黄在线观看 | 久久咪咪 | 91亚洲精品久久久蜜桃借种 |