查询排序_Mysql在排序和查询时不使用索引的情况
1. 寫在前頭
這篇文章《Mysql是怎樣運行的》,參考書中P123 - P125,它列舉的就是在排序時不使用索引的情況,這讓我回想起在面試的時候,被問到在查詢時不使用索引的情況,所以我想將這兩個問題匯總在一起,以便供大家參考。
2. 說前“熱身”
來,我們先建個表
create table single_table(id int not null auto_increment,key1 varchar(100),key2 int,key3 varchar(100),key_part1 varchar(100),key_part2 varchar(100),key_part3 varchar(100),common_field varchar(100),primary key (id),key idx_key1(key1),unique key uk_key2(key2),key idx_key3 (key3),key idx_key_part(key_part1, key_part2, key_part3))engine=InnoDB charset=utf8;喲!你給我寫這么長的代碼,你給我解釋解釋:
主要知道下面這些信息就行?
id列為聚簇索引?
key1列為二級索引
key2列唯一(unique)二級索引?
key3列為二級索引?
key_part1、key_part2、key_part3為三列的聯合索引(二級索引)
再插入10條數據,如下
這下準備差不多了,我們步入正題!
3. 在排序時不用索引的重頭戲
?ASC、DESC混用
以下這條代碼想讓key_part1列升序排列,key_part2降序排列是不會用到索引的
select key_part1, key_part2 from single_table order by key_part1, key_part2 desc;區(qū)別于以下代碼,這種情況會使用到我們的聯合索引
select key_part1, key_part2 from single_table order by key_part1, key_part2;注:這種情況適用于mysql8.0之前的版本,而在8.0版本會用到索引,分析語句和分析結果如下
explain select key_part1, key_part2 from single_table order by key_part1, key_part2 desc;
?排序列包含非用一個索引的列
因為key1和key2為非同一列的索引,在key1相同的情況下,是不會按照key2列進行排序,所以用不到索引
(explain)select id, key1, key2 from single_table order by key1, key2;分析結果如下
?排序列是某個聯合索引的索引列,但是這些排序列在聯合索引中并不連續(xù)
上代碼,一看就能明白!
select key_part1, key_part3 from single_table order by key_part1, key_part3;聯合索引在key_part1相同的時候,并不會按照key_part3排序,中間還有key_part2,所以不會用到聯合索引(但是mysql8.0會用到)
?用來形成掃描區(qū)間的索引列與排序列不同
先上代碼,咱再解釋
(explain) select id, key1, key2 from single_table where key1 < 'e' order by key2 desc;該語句形成的掃描區(qū)間是key < 'e',需要用到的索引是key1列的idx_key1,并不會用到key2列的索引uk_key2進行排序
分析結果如下
?排序列不是以單獨的列名出現在order by語句中
代碼哥哥!
(explain) select id, key1, key2 from single_table order by upper(key1);我們可以發(fā)現,在排序列中使用了函數upper(),所以排序時不會用到idx_key1索引
分析結果如下哎哎哎,我可是講完這節(jié)課了,數數一共幾種情況啊?
“五種!五種!”
行,那還不錯,喝口水咱接著看!
4. 在查詢時用不到索引的重頭戲
1.mysql認為使用索引相比于全表掃描更慢,則不使用索引
這種情況非常簡單,我一說大家就懂,寫條代碼
explain select * from single_table where key2 > 1;這條代碼,我們可能以為它會使用到idx_key2索引,其實不然,它采用的是全表掃描,看分析結果
2.如果查詢條件中用使用了or,即便其中某一列含有索引也不會用到
這個在網上查閱的資料,大多會說:用or分隔開的條件,如果or前的條件中的列有索引,而后面的列沒有索引,那么涉及到的索引都不會被用到 但是事實上,并不受在or前后的影響,看如下兩條語句
explain select * from single_table where id < 5 or common_field < 'f';分析結果為all,全表掃描我們把or前后的條件換一下再試
explain select * from single_table where common_field < 'f' or id < 5;仍然為全表掃描,所以索引列在or前后并無影響,都不走索引(特殊情況Union索引合并會用到索引)
3.對于聯合索引,如果沒用使用索引的第一部分,則不使用索引
簡單,上了代碼就能看明白
explain select * from single_table where key_part2 = 'e';聯合索引的第一部分為 key_part1,因為沒有使用到,所以不會用到聯合索引,對照如下分析結果
4.若模糊查詢以%開頭,不使用索引(太簡單,記住就行)5.如果列為字符串,則where條件中的字符常量必須加引號,否則用不到索引
我們寫兩個代碼對比一下就知道了
explain select * from single_table where key3 = 1;沒加引號的,分析結果如下,全表掃描我們給常量加上引號再寫一個
explain select * from single_table where key3 = '1';這下分析結果中,就顯示用引號了
okk,同學們,這節(jié)課就上到這,我們下次見!
文末彩蛋
最近讀完了《干法》,一本兒也算不錯的書。
剛開始讀這本書的時候,覺得作者好像一個固執(zhí)的“傻”老頭,對自己要求及其嚴苛,凡事都要盡善盡美,而且專干沒人干的事兒(不走尋常路),同樣,他對自己的員工也要求極高,連桌上的文件都要放的與桌子邊齊平,萬事都不能馬虎
其實讀到這里的時候,我覺得這本書已經沒有這么吸引我了,好像與市面兒上的自我激勵的書沒什么兩樣
不過文末穿插了一篇老先生在杭州的一篇演講,給我留下了及其深刻的印象,先前心里留下的成見可以說一下就打消了
老先生講了自己的故事、事業(yè)和行事的態(tài)度,可以感覺到老先生是一個非常非常真誠的人,而且其中有一段話令我印象深刻,我寫在下面
付出以筆舌難以道盡的辛勞,勤奮努力、拼命奮斗、守護公司、守護員工、守護社會,感覺到自己在做這些好事的時候,我們經營者同時也能感到喜悅和快樂,我認為,感覺到這種喜悅和快樂就是我們經營者最大的幸福
他的出發(fā)點并不是為自己謀求最大的利益,而是心系家人、員工和社會,認為自己有極大的責任要為員工的幸福和社會的發(fā)展負責,這一點就很觸動我,而且他講到日后創(chuàng)辦的企業(yè),他并不持有股份,也是做到了他的知行合一。
雖然稻盛的行為準則,作為一個普通人難以企及,但是他帶給我的觸動更能讓我想做一個踏實、肯干的人,耐心的往下走,不著急,慢慢來,也許只有那些真正做到稻盛要求的那些準則的人,才能對他說的話有更深的理解吧...
祝大家生活愉快!
總結
以上是生活随笔為你收集整理的查询排序_Mysql在排序和查询时不使用索引的情况的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 满意度调查access模板_洪安镇推进综
- 下一篇: css before 文字前面竖线_前端