淺談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)文章
SQL語(yǔ)句實(shí)現(xiàn)SQL Server 2000及Sql Server 2005日志收縮(批量)
SQL語(yǔ)句實(shí)現(xiàn)SQL Server 2000及Sql Server 2005日志收縮(批量)2008-08-08SQL SERVER 與ACCESS、EXCEL的數(shù)據(jù)轉(zhuǎn)換
SQL SERVER 與ACCESS、EXCEL的數(shù)據(jù)轉(zhuǎn)換...2006-07-07SQL?Server快速?gòu)氐仔遁d實(shí)例方法分享
最近在安裝了SQL Server后,當(dāng)由于某些原因我們需要卸載它時(shí),我們應(yīng)該怎么操作呢?這篇文章主要給大家介紹了關(guān)于SQL?Server快速?gòu)氐仔遁d的相關(guān)資料,需要的朋友可以參考下2023-10-10SQL SERVER 數(shù)據(jù)類型詳解補(bǔ)充2
之前腳本之家發(fā)過(guò)數(shù)據(jù)類型方面的文章,但內(nèi)容不是很充實(shí),這里的一篇文章,正好彌補(bǔ)以前的一些,建議這兩篇文章一起看效果更好。2010-04-04SQLServer 數(shù)據(jù)庫(kù)的數(shù)據(jù)匯總完全解析(WITH ROLLUP)
乍一看,好像很容易,用group by好像能實(shí)現(xiàn)?但仔細(xì)研究下去,你又會(huì)覺得group by也是無(wú)能為力,總欠缺點(diǎn)什么,無(wú)從下手。那么,到底該如何做呢?別急,SQL Server早就幫我們做好了,下面,跟我來(lái)。2010-09-09通過(guò)分析SQL語(yǔ)句的執(zhí)行計(jì)劃優(yōu)化SQL
基于代價(jià)的優(yōu)化器是很聰明的,在絕大多數(shù)情況下它會(huì)選擇正確的優(yōu)化器,減輕了DBA的負(fù)擔(dān)。但有時(shí)它也聰明反被聰明誤,選擇了很差的執(zhí)行計(jì)劃,使某個(gè)語(yǔ)句的執(zhí)行變得奇慢無(wú)比2011-10-10SQL SERVER 數(shù)據(jù)庫(kù)備份的三種策略及語(yǔ)句
這篇文章主要介紹了SQL SERVER 數(shù)據(jù)庫(kù)備份的三種策略及語(yǔ)句,需要的朋友可以參考下2017-02-02sqlserver中操作主從關(guān)系表的sql語(yǔ)句
在項(xiàng)目開發(fā)中,經(jīng)常出現(xiàn)這樣的需求。在新增或修改一個(gè)主表數(shù)據(jù)時(shí),對(duì)應(yīng)的從表也要進(jìn)行同步,此時(shí)我們是怎么操作的了?2011-07-07SQL?Server?2008?R2完美卸載教程(親測(cè)有用)
SQL Server 2008 R2是一款非常強(qiáng)大的數(shù)據(jù)庫(kù)管理系統(tǒng),但在某些情況下可能需要卸載它,下面這篇文章主要給大家介紹了關(guān)于SQL?Server?2008?R2完美卸載的相關(guān)資料,需要的朋友可以參考下2023-11-11