mysql不走索引的幾個(gè)問題小結(jié)
一、類型不匹配導(dǎo)致不走索引
這類問題往往是因?yàn)閿?shù)據(jù)定義與使用上面的偏差,比如工號(hào),定義成varchar,然而用的時(shí)候又不講工號(hào)打上引號(hào)
創(chuàng)建表代碼舉例如下:
----創(chuàng)建表: CREATE TABLE `test_a`( `id` int(11) NOT NULL, `work_no` varchar(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `index_work_no`(`work_no`) )ENGINE=InnoDB;
查詢條件對(duì)比如下:
----查詢工號(hào),執(zhí)行一下----- explain SELECT * from test_a where work_no=1000; explain SELECT * from test_a where work_no="1000";
結(jié)論,可以自己運(yùn)行一下代碼,會(huì)發(fā)現(xiàn)上面的因?yàn)槎x成了varchar,但是用的時(shí)候又在把它當(dāng)int用,沒有加引號(hào),導(dǎo)致無法走索引
二、索引用錯(cuò)的問題
這個(gè)是索引用錯(cuò)的問題,創(chuàng)建表及初始化數(shù)據(jù)代碼如下:
----創(chuàng)建表: CREATE TABLE `test_t`( `id` int(11) NOT NULL, `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `index_a`(`a`), KEY`index_b`(`b`) )ENGINE=InnoDB; -----定義初始化10w數(shù)據(jù)函數(shù): delimiter;; create procedure idata() begin declare i int; set i=1; while(i<=100000) do insert into test_t values(i,i,i); set i=i+1; end while; end;; delimiter; call idata(); ----刪除存儲(chǔ)過程 drop procedure idata;
相關(guān)查詢對(duì)比:
----查詢條件 explain select * from test_t where (a BETWEEN 1 and 1000) and (b BETWEEN 50000 and 100000) order by b limit 1; explain select * from test_t force index(index_a) where (a BETWEEN 1 and 1000) and (b BETWEEN 50000 and 100000) order by b limit 1;
結(jié)論,最終出現(xiàn)第一個(gè)走錯(cuò)了索引,導(dǎo)致查詢時(shí)候會(huì)變長(zhǎng)的問題。
而下面的我們加強(qiáng)制走索引,會(huì)發(fā)現(xiàn)執(zhí)行掃描行數(shù)要少很多,主要原因還是發(fā)生在order上
如果做下面的修改不強(qiáng)制走索引也能夠走正確的索引就是order by b, a。同時(shí)放上去也是有效的
三、條件字段為函數(shù)的操作導(dǎo)致不走索引
函數(shù)作用在索引字段上導(dǎo)致不走索引,其實(shí)感覺mysql盡量少用函數(shù),雖然提供了,往往還是占用的mysql自己的資源做的計(jì)算。mysql數(shù)據(jù)庫的資源多貴呀,物理機(jī)多便宜呀
----創(chuàng)建表: CREATE TABLE `trade_log`( `id` int(11) NOT NULL, `created_time` datetime NOT NULL DEFAULT, `b` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `index_created_time`(`created_time`) )ENGINE=InnoDB; -----定義初始化10w數(shù)據(jù)函數(shù): delimiter;; create procedure c_trade_log() begin declare i int; set i=1; while(i<=100000) do insert into trade_log values(i,from_unixtime(1539123415 + 1000*i),i); set i=i+1; end while; end;; delimiter; call c_trade_log(); ----刪除存儲(chǔ)過程 DROP PROCEDURE c_trade_log
查詢條件:
explain SELECT count(*) from trade_log where month(created_time)=7; SELECT count(*) from trade_log where month(created_time)=7; -----優(yōu)化----- explain SELECT count(*) from trade_log where created_time BETWEEN "2018-07-01" and "2018-08-01" or created_time BETWEEN "2019-07-01" and "2019-08-01" or created_time BETWEEN "2020-07-01" and "2020-08-01" or created_time BETWEEN "2021-07-01" and "2021-08-01" ;
四、錯(cuò)誤計(jì)算不走索引
查詢條件:繼續(xù)沿用上面的trade_log表
索引字段做減法在等號(hào)前,與等號(hào)后的區(qū)別
--不走索引 explain SELECT * from trade_log where id -1000=3030300 --走索引 explain SELECT * from trade_log where id =3030300-1000
五、in后面的公式
繼續(xù)使用test_t表
--不走索引 因?yàn)橛衜ax,不要究竟這兒為什么要加max公式,主要是為了突出這兒不走索引給的一個(gè)例子 explain select * FROM test_t WHERE id IN ( SELECT max(id) FROM test_t WHERE a BETWEEN 1000 and 2000 GROUP BY a ) --走索引 explain select * FROM test_t WHERE id IN ( SELECT id FROM test_t WHERE a BETWEEN 1000 and 2000 GROUP BY a )
不走索引的結(jié)果:
走索引的結(jié)果:
其他:慢sql相關(guān)配置開啟命令
----慢查詢開啟情況--- show variables like "slow_query_log"; ----設(shè)置開啟---- set global slow_query_log = "ON"; ---慢查詢?nèi)罩镜刂?-- show variables like "slow_query_log_file";
到此這篇關(guān)于mysql不走索引的幾個(gè)問題小結(jié)的文章就介紹到這了,更多相關(guān)mysql不走索引內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Sql Server數(shù)據(jù)庫遠(yuǎn)程連接訪問設(shè)置詳情
這篇文章主要介紹了Sql Server數(shù)據(jù)庫遠(yuǎn)程連接訪問設(shè)置詳情,文章圍繞主題展開詳細(xì)的內(nèi)容戒殺,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-09-09MySql中把一個(gè)表的數(shù)據(jù)插入到另一個(gè)表中的實(shí)現(xiàn)代碼
本篇文章是對(duì)MySql中把一個(gè)表的數(shù)據(jù)插入到另一個(gè)表中的實(shí)現(xiàn)代碼進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05簡(jiǎn)單了解mysql存儲(chǔ)字段類型查詢效率
這篇文章主要介紹了簡(jiǎn)單了解mysql存儲(chǔ)字段類型查詢效率,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09mysql觸發(fā)器一個(gè)表改變另一個(gè)表也改變問題
這篇文章主要介紹了mysql觸發(fā)器一個(gè)表改變另一個(gè)表也改變問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08