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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > 数据库 >内容正文

数据库

《MySQL——使用联合索引、覆盖索引,避免临时表的排序操作》

發(fā)布時(shí)間:2023/12/1 数据库 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《MySQL——使用联合索引、覆盖索引,避免临时表的排序操作》 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

聯(lián)合索引避免臨時(shí)表排序

在上一篇筆記(MySQL——order by邏輯(全字段排序與rowid排序))中,講到查詢語(yǔ)句查詢多個(gè)字段的時(shí)候使用order by語(yǔ)句實(shí)現(xiàn)返回值是有序的,而order by是使用到了臨時(shí)表的,會(huì)帶來(lái)時(shí)間和空間損失。
其實(shí)使用聯(lián)合索引,就可以避免臨時(shí)表的排序操作。
只要保證city這個(gè)索引上取出來(lái)的行天然就是按照name遞增排序的話,就可以不用再排序了。

alter table t add index city_user(city,name);

在這個(gè)索引里面,通過(guò)樹(shù)搜索的方式定位到第一個(gè)滿足city = '杭州’的記錄,并且額外確保了,接下來(lái)按順序取“下一條記錄”的遍歷過(guò)程中,只要city值是杭州,name值一定有序。
查詢流程變?yōu)?#xff1a;
1、從索引(city,name)找到第一個(gè)滿足city = '杭州’條件的主鍵id;
2、到主鍵id索引取出整行,取name、city、age三個(gè)字段值,作為結(jié)果集的一部分直接返回
3、從索引(city,name)取下一個(gè)記錄主鍵id;
4、重復(fù)step2、3直到查到第1000條記錄,或者不滿足city = '杭州’條件時(shí)循環(huán)結(jié)束。

覆蓋索引優(yōu)化查詢

可以使用覆蓋索引繼續(xù)優(yōu)化查詢的執(zhí)行流程:
覆蓋索引指,索引上的信息足夠滿足查詢請(qǐng)求,不需要再回到主鍵索引上取數(shù)據(jù)。
針對(duì)select city,name,age from t 這個(gè)查詢,可以創(chuàng)建一個(gè)city、name和age的聯(lián)合索引,對(duì)應(yīng)語(yǔ)句為:

alter table t add index city_user_age(city,name,age);

這時(shí),對(duì)于city字段的值相同的行來(lái)說(shuō),還是按照name字段的值遞增排序。查詢語(yǔ)句的執(zhí)行流程變?yōu)?#xff1a;
1、從索引(city,name,age)找到第一個(gè)滿足city = '杭州’條件的記錄,取出其中的city、name和age三個(gè)字段值,作為結(jié)果集的一部分直接返回
2、從索引(city,name,age)取下一個(gè)記錄,同樣取出這三個(gè)字段的值,作為結(jié)果集的一部分直接返回
3、重復(fù)步驟2,直到查到第1000條記錄,或者是不滿足city = '杭州’條件時(shí)循環(huán)結(jié)束。

當(dāng)然,并不是說(shuō)每個(gè)查詢能用上覆蓋索引,就要把語(yǔ)句中涉及的字段都建上聯(lián)合索引。因?yàn)樗饕芯S護(hù)代價(jià)。

思考

假設(shè)表里面已經(jīng)有了city_name(city,name)聯(lián)合索引。你需要查詢杭州和蘇州兩個(gè)城市中所有市民的名字,并且按名字排序,顯示前100條記錄。

select * from t where city in('杭州','蘇州') order by name limit 100;

這個(gè)語(yǔ)句會(huì)有排序。因?yàn)闂l件是蘇州或杭州。如果只有一個(gè)條件如只有杭州,那么就不需要排序操作。
如果我們需要實(shí)現(xiàn)一個(gè)在數(shù)據(jù)庫(kù)端不需要排序的方案,可以這么實(shí)現(xiàn):
把這一條語(yǔ)句拆成兩條語(yǔ)句,流程如下:
1、執(zhí)行select * from t where city = '杭州' order by name limit 100;
(這個(gè)語(yǔ)句不需要排序,客戶端用一個(gè)長(zhǎng)度為100的內(nèi)存數(shù)組A保存結(jié)果)
2、執(zhí)行select * from where city = '蘇州' order by name limit 100;
(相同的方法,結(jié)果被存入內(nèi)存數(shù)組B)
3、對(duì)AB兩個(gè)有序數(shù)組采用歸并排序,得到name最小的前100值,這就是我們需要的結(jié)果了。

總結(jié)

以上是生活随笔為你收集整理的《MySQL——使用联合索引、覆盖索引,避免临时表的排序操作》的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。