mysqlunionall無法走索引11 27
我們提供的服務有:網(wǎng)站設計、成都網(wǎng)站制作、微信公眾號開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認證、壽縣ssl等。為近千家企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務,是有科學管理、有技術的壽縣網(wǎng)站制作公司
1. like %%失效。 方案:改為like %,只寫后面的%就能走索引。
2. 雖然有索引,但是查詢條件沒有索引列或者order by 排序沒有索引列。 方案:讓查詢條件有索引列
3. 索引列存在null值的情況。 方案:索引列如果沒有值,則給空字符串或者數(shù)字的0,總之就是不要設置null
SQL的執(zhí)行成本(cost)是 MySQL 優(yōu)化器選擇 SQL 執(zhí)行計劃時一個重要考量因素。當優(yōu)化器認為使用索引的成本高于全表掃描的時候,優(yōu)化器將會選擇全表掃描,而不是使用索引。
下面通過一個實驗來說明。
如下結構的一張表,表中約有104w行數(shù)據(jù):
查詢1,并未用到ct_index(create_time)索引:
而查詢2,則用到了ct_index(create_time)索引:
這里使用optimizer trace工具,觀察MySQL對SQL的優(yōu)化處理過程:
獲得關于此SQL的詳細優(yōu)化器處理信息:
通過逐行閱讀,發(fā)現(xiàn)優(yōu)化器在join_optimization(SQL優(yōu)化階段)部分的rows_estimation內(nèi)容里:
通過觀察優(yōu)化器的信息,不難發(fā)現(xiàn),使用索引掃描行數(shù)約52w行,而全表掃描約為104w行。為什么優(yōu)化器反而認為使用索引的成本比全表掃描還高呢?
因為當ct_index(create_time)這個普通索引并不包括查詢的所有列,因此需要通過ct_index的索引樹找到對應的主鍵id,然后再到id的索引樹進行數(shù)據(jù)查詢,即回表(通過索引查出主鍵,再去查數(shù)據(jù)行),這樣成本必然上升。尤其是當回表的數(shù)據(jù)量比較大的時候,經(jīng)常會出現(xiàn)MySQL優(yōu)化器認為回表查詢代價過高而不選擇索引的情況。
這里可以回頭看查詢1 和 查詢2的數(shù)據(jù)量占比:
另外,在MySQL的官方文檔中對此也有簡要的描述:
參考文檔:
2020-02-27
最近一個日志頁面查詢很慢,然后去跟蹤了查詢sql,發(fā)現(xiàn)日期字段上即使建了索引,查詢還是很慢,執(zhí)行語句還是使用了全表掃描,于是繼續(xù)分析下去。
查詢語句類似:
select * from logs where createtime = '2020-01-01' ;
起初因為date上沒檢索,查詢執(zhí)行的是全表掃描,給條件字段createtime建上索引:
再次執(zhí)行:
查詢執(zhí)行的還是全表掃描:
網(wǎng)上查詢有說是因為在查詢數(shù)據(jù)條數(shù)約占總條數(shù)五分之一以下時能夠使用到索引,但超過五分之一時,使用全表掃描。于是把日期范圍縮?。?/p>
果真,查詢執(zhí)行的是range:
由此可知,在進行范圍查詢時,比如:、 、=、=等, 如果數(shù)據(jù)量過大的話,即使where條件字段已經(jīng)建立了索引,查詢語句執(zhí)行時還是有可能進行全表掃描的。
實際上是不是全表的五分之一以下才會使用索引,這個不能確定,以后再研究了。
原因有如下:
1、最佳左前綴原則——如果索引了多列,要遵守最左前綴原則。指的是查詢要從索引的最左前列開始并且不跳過索引中的列。
2、不在索引列上做任何操作,會導致索引失效而導致全表掃描。
3、存儲引擎不能使用索引中范圍條件右邊的列,范圍之后索引失效。這寫條件判斷最后放到后面,先定位到小的范圍再開始。
4、mysql使用不等于(!= 或者)的時候,無法使用索引,會導致索引失效。
5、mysql中使用is not null 或者 is null會導致無法使用索引。
6、mysql中l(wèi)ike查詢是以%開頭,索引會失效變成全表掃描,覆蓋索引。
7、mysql中,如果條件中有or,即使其中有條件帶索引也不會使用(這也是為什么盡量少用or的原因)。要想使用or,又想讓索引生效,只能將or條件中的每個列都加上索引。
8、如果mysql使用全表掃描要比使用索引快,則不會使用到索引。
注意事項
1、索引列有函數(shù)處理或隱式轉換,不走索引。
2、索引列傾斜,個別值查詢時,走索引代價比走全表掃描高,所以不走索引。
3、索引列沒有限制 not null,索引不存儲空值,如果不限制索引列是not null,oracle會認為索引列有可能存在空值,所以不會按照索引計算。
分享標題:mysql怎么會不走索引,sql查詢不走索引
路徑分享:http://www.muchs.cn/article22/hchocc.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供移動網(wǎng)站建設、手機網(wǎng)站建設、面包屑導航、域名注冊、定制網(wǎng)站、網(wǎng)站維護
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)