淺談SQL不走索引的幾種常見情況
我們寫的SQL語(yǔ)句很多時(shí)候where條件用到了添加索引的列,但是卻沒有走索引,在網(wǎng)上找了資料,發(fā)現(xiàn)不是很準(zhǔn)確,所以自己驗(yàn)證了一下,記一下筆記。
這里實(shí)驗(yàn)數(shù)據(jù)庫(kù)為 MySQL(oracle也類似)。
查看表的索引的語(yǔ)句: show keys from 表名
查看SQL執(zhí)行計(jì)劃的語(yǔ)句(SQL語(yǔ)句前面添加 explain 關(guān)鍵字):explain select* from users u where u.name = 'mysql測(cè)試'
第一步、創(chuàng)建一個(gè)簡(jiǎn)單的表并添加幾條測(cè)試數(shù)據(jù)
CREATE TABLE `users` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(255) DEFAULT NULL, `password` varchar(255) DEFAULT NULL, `name` varchar(255) DEFAULT NULL, `upTime` datetime DEFAULT NULL, PRIMARY KEY (`id`), KEY `pk_users_name` (`name`) ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;
設(shè)置索引的字段:id、name;
第二步、查看我們表的索引
# 查看索引 show keys from users
可以得到如下信息,其中id、name及為我們建的索引

第三步、通過(guò)執(zhí)行計(jì)劃查看我們的SQL是否使用了索引
執(zhí)行如下語(yǔ)句得到:
explain select * from users u where u.name = 'mysql測(cè)試'

字段說(shuō)明:
type列,連接類型。一個(gè)好的SQL語(yǔ)句至少要達(dá)到range級(jí)別。杜絕出現(xiàn)all級(jí)別。
possible_keys: 表示查詢時(shí)可能使用的索引。
key列,使用到的索引名。如果沒有選擇索引,值是NULL??梢圆扇?qiáng)制索引方式。
key_len列,索引長(zhǎng)度。
rows列,掃描行數(shù)。估算的找到所需的記錄所需要讀取的行數(shù)。
extra列,詳細(xì)說(shuō)明。注意,常見的不太友好的值,如下:Using filesort,Using temporary。
從這里可以看出,我們使用了索引,因?yàn)閚ame是加了索引的;
tryp說(shuō)明:
- ALL: 掃描全表
- index: 掃描全部索引樹
- range: 掃描部分索引,索引范圍掃描,對(duì)索引的掃描開始于某一點(diǎn),返回匹配值域的行,常見于between、<、>等的查詢
- ref: 使用非唯一索引或非唯一索引前綴進(jìn)行的查找
- eq_ref:唯一性索引掃描,對(duì)于每個(gè)索引鍵,表中只有一條記錄與之匹配。常見于主鍵或唯一索引掃描
- const, system: 單表中最多有一個(gè)匹配行,查詢起來(lái)非常迅速,例如根據(jù)主鍵或唯一索引查詢。system是const類型的特例,當(dāng)查詢的表只有一行的情況下, 使用system。
不走索引的情況,例如:
執(zhí)行語(yǔ)句:
# like 模糊查詢 前模糊或者 全模糊不走索引 explain select * from users u where u.name like '%mysql測(cè)試'

可以看出,key 為null,沒有走索引。
下面是幾種測(cè)試?yán)?
# like 模糊查詢 前模糊或者 全模糊不走索引
explain select * from users u where u.name like '%mysql測(cè)試'
# or 條件不走索引,只要有一個(gè)條件字段沒有添加索引,都不走,如果條件都添加的索引,也不一定,測(cè)試
的時(shí)候發(fā)現(xiàn)有時(shí)候走,有時(shí)候不走,可能數(shù)據(jù)庫(kù)做了處理,具體需要先測(cè)試一下
explain select * from users u where u.name = 'mysql測(cè)試' or u.password ='JspStudy'
# or 條件都是同一個(gè)索引字段,走索引
explain select * from users u where u.name= 'mysql測(cè)試' or u.name='333'
# 使用 union all 代替 or 這樣的話有索引例的就會(huì)走索引
explain
select * from users u where u.name = 'mysql測(cè)試'
union all
select * from users u where u.password = 'JspStudy'
# in 走索引
explain select * from users u where u.name in ('mysql測(cè)試','JspStudy')
# not in 不走索引
explain select * from users u where u.name not in ('mysql測(cè)試','JspStudy')
# is null 走索引
explain select * from users u where u.name is null
# is not null 不走索引
explain select * from users u where u.name is not null
# !=、<> 不走索引
explain select * from users u where u.name <> 'mysql測(cè)試'
# 隱式轉(zhuǎn)換-不走索引(name 字段為 string類型,這里123為數(shù)值類型,進(jìn)行了類型轉(zhuǎn)換,所以不走索引,改為 '123' 則走索引)
explain select * from users u where u.name = 123
# 函數(shù)運(yùn)算-不走索引
explain select * from users u where date_format(upTime,'%Y-%m-%d') = '2019-07-01'
# and 語(yǔ)句,多條件字段,最多只能用到一個(gè)索引,如果需要,可以建組合索引
explain select * from users where id='4' and username ='JspStudy' 做SQL優(yōu)化,我們最好用 explain 查看SQL執(zhí)行計(jì)劃,理論不一定正確,而且不同的數(shù)據(jù)庫(kù),不同的sql語(yǔ)句可能有不同的結(jié)果,最好是一邊測(cè)試一邊優(yōu)化。
到此這篇關(guān)于淺談SQL不走索引的幾種常見情況的文章就介紹到這了,更多相關(guān)SQL不走索引內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
sqlserver (parse name)字符串截取的方法
sqlserver (parse name)字符串截取的方法,需要的朋友可以參考一下2013-04-04
一個(gè)基于ROW_NUMBER()的通用分頁(yè)存儲(chǔ)過(guò)程代碼
項(xiàng)目中有很多小型的表(數(shù)據(jù)量不大),都需要實(shí)現(xiàn)分頁(yè)查詢,因此實(shí)現(xiàn)了一個(gè)通用的分頁(yè)。2010-10-10
sqlserver 手工實(shí)現(xiàn)差異備份的步驟
sqlserver 手工實(shí)現(xiàn)差異備份的步驟,需要的朋友可以參考下。2011-04-04
SQL Server的Descending Indexes降序索引實(shí)例展示
在涉及多字段排序的復(fù)雜查詢中,合理使用降序索引可以顯著提升SQLServer的查詢效率,本文通過(guò)構(gòu)建實(shí)際的查詢案例,展示了如何在SQLServer中建立并利用降序索引優(yōu)化查詢性能,感興趣的朋友一起看看吧2024-09-09
SQL?Server?2022最新下載安裝教程(圖文詳細(xì)?)
這篇文章詳細(xì)介紹了如何下載和安裝SQL?Server?2022,并創(chuàng)建了一個(gè)自定義命名實(shí)例,安裝過(guò)程中包括選擇安裝位置、配置數(shù)據(jù)庫(kù)引擎服務(wù)、設(shè)置混合模式身份驗(yàn)證以及創(chuàng)建桌面快捷方式2026-02-02
解決sql server保存對(duì)象字符串轉(zhuǎn)換成uniqueidentifier失敗的問(wèn)題
這篇文章主要介紹了解決sql server保存對(duì)象字符串轉(zhuǎn)換成uniqueidentifier失敗的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-10-10
SQL冪運(yùn)算 POW() and POWER()函數(shù)用法小結(jié)
本文主要介紹了SQL冪運(yùn)算 POW() and POWER()函數(shù)用法小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-09-09
安裝SQL Server 2016出錯(cuò)提示:需要安裝oracle JRE7 更新 51(64位)或更高版本問(wèn)題的解決方法
這篇文章主要介紹了安裝SQL Server 2016出錯(cuò)提示:需要安裝oracle JRE7 更新 51(64位)或更高版本問(wèn)題的解決方法,需要的朋友可以參考下2018-03-03
mssql和sqlite中關(guān)于if not exists 的寫法
本文介紹下sql server查詢中,有關(guān)if exists與if not exists關(guān)鍵字的用法,有需要的朋友參考下2014-04-04

