日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

浅析索引失效(一)

發(fā)布時間:2024/2/28 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 浅析索引失效(一) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

先在重復一下,什么是索引?

MySQL索引的建立對于MySQL的高效運行是很重要的,索引可以大大提高MySQL的檢索速度。

但是在生產中,我們有時候會發(fā)現(xiàn),某一條sql速度慢的出奇,原因可能就是語句中的某些表示,導致了索引失效。

以下針對索引失效的幾種看法!歡迎交流!!!


一、查詢條件中包含or,可能導致索引失效。

新建一個普通表employees,

CREATE TABLE `emp` (`id` int(11) NOT NULL,`emp_no` int(11) NOT NULL,`birth_date` date NOT NULL,`first_name` varchar(14) NOT NULL,`last_name` varchar(16) NOT NULL,`gender` char(1) NOT NULL,`hire_date` date NOT NULL,PRIMARY KEY (`id`),KEY `idx_emp_no` (`emp_no`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

插入少量元素,意思意思?

INSERT INTO `emp` VALUES ('1','10001', '1953-09-02', 'Georgi', 'Facello', 'M', '1986-06-26'); INSERT INTO `emp` VALUES ('2','10002', '1964-06-02', 'Bezalel', 'Simmel', 'F', '1985-11-21'); INSERT INTO `emp` VALUES ('3','10003', '1959-12-03', 'Parto', 'Bamford', 'M', '1986-08-28'); INSERT INTO `emp` VALUES ('4','10004', '1954-05-01', 'Chirstian', 'Koblick', 'M', '1986-12-01'); INSERT INTO `emp` VALUES ('5','10005', '1955-01-21', 'Kyoichi', 'Maliniak', 'M', '1989-09-12'); INSERT INTO `emp` VALUES ('6','10006', '1953-04-20', 'Anneke', 'Preusig', 'F', '1989-06-02'); INSERT INTO `emp` VALUES ('7','10007', '1957-05-23', 'Tzvetan', 'Zielinski', 'F', '1989-02-10'); INSERT INTO `emp` VALUES ('8','10008', '1958-02-19', 'Saniya', 'Kalloufi', 'M', '1994-09-15'); INSERT INTO `emp` VALUES ('9','10009', '1952-04-19', 'Sumant', 'Peac', 'F', '1985-02-18'); INSERT INTO `emp` VALUES ('10','10010', '1963-06-01', 'Duangkaew', 'Piveteau', 'F', '1989-08-24'); INSERT INTO `emp` VALUES ('11','10011', '1953-11-07', 'Mary', 'Sluis', 'F', '1990-01-22');

1.執(zhí)行一條sql語句,它是會走索引的,如下圖所示:

如果你沒有使用過explain這個命令來查看SQL語句的執(zhí)行計劃,這里走:https://georgedage.blog.csdn.net/article/details/103526199

或者,繼續(xù)看:

喬治大哥

?

2.把or條件+沒有索引的age加上,并不會走索引,如圖所示

分析&結論:

  • 對于or+沒有索引的age這種情況,假設它走了emp_no的索引,但是走到gender查詢條件時,它還得全表掃描,也就是需要三步過程:全表掃描+索引掃描+合并

  • 如果它一開始就走全表掃描,直接一遍掃描就完事。

  • mysql是有優(yōu)化器的,處于效率與成本考慮,遇到or條件,讓索引失效,看起來也合情合理嘛。

注意: 如果or條件的列都加了索引,索引可能會走的,大家可以自己試一試。


二、如何字段類型是字符串,where時一定用引號括起來,否則索引失效

再創(chuàng)個表:?

CREATE TABLE `emp2` (`id` int(11) NOT NULL,`emp_no` varchar(14) NOT NULL,`birth_date` date NOT NULL,`first_name` varchar(14) NOT NULL,`last_name` varchar(16) NOT NULL,`gender` char(1) NOT NULL,`hire_date` date NOT NULL,PRIMARY KEY (`id`),KEY `idx_emp_no` (`emp_no`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

然后接下來看兩種情況:

分析與結論:

為什么第一條語句未加單引號就不走索引了呢?這是因為不加單引號時,是字符串跟數(shù)字的比較,它們類型不匹配,MySQL會做隱式的類型轉換,把它們轉換為浮點數(shù)再做比較。


三、like通配符可能導致索引失效。

在emp2表中,當%在前面不走索引,%在后面的話走索引。

喬治大哥

?在emp表中,當%無論前后都是不走索引,這個我覺得還是想我們二中所說的在底層mysql進行了轉化,因為emp表中的emp_no是int類型。

喬治大哥

然后給大家一個意想不到的:改為只查索引的字段(覆蓋索引),發(fā)現(xiàn)還是走索引

結論:

like查詢以%開頭,會導致索引失效。可以有兩種方式優(yōu)化:

  • 使用覆蓋索引

  • 把%放后面

附: 索引包含所有滿足查詢需要的數(shù)據(jù)的索引,稱為覆蓋索引(Covering Index)。


四、聯(lián)合索引,查詢時的條件列不是聯(lián)合索引中的第一個列,索引失效

表結構:(有一個聯(lián)合索引 idx_emp_no_age,emp_no在前, age在后)

CREATE TABLE `emp3` (`id` int(11) NOT NULL,`emp_no` int(11) NOT NULL,`age` int(11) NOT NULL,PRIMARY KEY (`id`),KEY `idx_emp_no_age` (`emp_no`,`age`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

在聯(lián)合索引中,查詢條件滿足最左匹配原則時,索引才是正常生效的。請看demo:

喬治大哥 喬治大哥 喬治大哥
?

【友情補充】index這種連接類型只是另外一種形式的全表掃描,只不過它的掃描順序是按照索引的順序。這種掃描根據(jù)索引然后回表取數(shù)據(jù)

分析與結論:

  • 當我們創(chuàng)建一個聯(lián)合索引的時候,如(k1,k2,k3),相當于創(chuàng)建了(k1)、(k1,k2)和(k1,k2,k3)三個索引,這就是最左匹配原則

  • 聯(lián)合索引不滿足最左原則,索引一般會失效,但是這個還跟Mysql優(yōu)化器有關的。


五、在索引列上使用mysql的內置函數(shù),索引失效。

創(chuàng)表:

CREATE TABLE `emp4` (`id` int(11) NOT NULL,`emp_no` int(11) NOT NULL,`logintime` datetime NOT NULL,PRIMARY KEY (`id`),KEY `idx_emp_no` (`emp_no`) USING BTREE,KEY `idx_login_time` (`loginTime`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Demo:?

喬治大哥

雖然loginTime加了索引,但是因為使用了mysql的內置函數(shù)Date_ADD(),索引直接GG,如圖:?

喬治大哥
?

?

總結

以上是生活随笔為你收集整理的浅析索引失效(一)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。