SQL優(yōu)化之索引失效

盡量全值匹配

建表語句:

CREATE TABLE `t_logs` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `action` varchar(100) DEFAULT NULL,
  `data` varchar(2000) DEFAULT NULL,
  `author_id` int(10) DEFAULT NULL,
  `ip` varchar(20) DEFAULT NULL,
  `created` int(10) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `actionipcreated` (`action`,`created`,`ip`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=938 DEFAULT CHARSET=utf8;

其中有三個(gè)字段是聯(lián)合索引火鼻,在查詢的時(shí)候盡量把where條件跟索引全量匹配室囊,例如:

EXPLAIN select * from t_logs where action = '訪客訪問' and created = '1528366547' and ip = '58.135.82.57';

執(zhí)行計(jì)劃:

+----+-------------+--------+------------+------+-----------------+-----------------+---------+-------------------+------+----------+-------+
| id | select_type | table  | partitions | type | possible_keys   | key             | key_len | ref               | rows | filtered | Extra |
+----+-------------+--------+------------+------+-----------------+-----------------+---------+-------------------+------+----------+-------+
|  1 | SIMPLE      | t_logs | NULL       | ref  | actionipcreated | actionipcreated | 371     | const,const,const |    1 |   100.00 | NULL  |
+----+-------------+--------+------------+------+-----------------+-----------------+---------+-------------------+------+----------+-------+

如果條件不允許使用索引列的全局匹配,那么最好使用覆蓋索引魁索,比如:

EXPLAIN select action,created,ip from t_logs where action = '訪客訪問';

執(zhí)行計(jì)劃:

+----+-------------+--------+------------+------+-----------------+-----------------+---------+-------+------+----------+-------------+
| id | select_type | table  | partitions | type | possible_keys   | key             | key_len | ref   | rows | filtered | Extra       |
+----+-------------+--------+------------+------+-----------------+-----------------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | t_logs | NULL       | ref  | actionipcreated | actionipcreated | 303     | const |  195 |   100.00 | Using index |
+----+-------------+--------+------------+------+-----------------+-----------------+---------+-------+------+----------+-------------+

最佳左前綴法則

如果索引了多列融撞,要遵守最左前綴法則。指的是查詢從索引的最左前列開始并且不跳過索引中的列粗蔚。

建表語句:

CREATE TABLE `t_logs` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `action` varchar(100) DEFAULT NULL,
  `data` varchar(2000) DEFAULT NULL,
  `author_id` int(10) DEFAULT NULL,
  `ip` varchar(20) DEFAULT NULL,
  `created` int(10) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `actionipcreated` (`action`,`created`,`ip`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=938 DEFAULT CHARSET=utf8;

可見尝偎,一個(gè)復(fù)合索引,順序是action,created致扯,ip肤寝,當(dāng)在使用這三個(gè)索引作為條件查詢的時(shí)候可以打亂順序,但不能跳過抖僵。

舉例:

正確的利用了索引的查詢語句:

EXPLAIN select * from t_logs where action = '訪客訪問' and created = '1528366547' and ip = '58.135.82.57';

未全部利用索引進(jìn)行的查詢:

EXPLAIN select * from t_logs where action = '訪客訪問' and ip = '58.135.82.57';

上面的sql語句僅有action列上的索引起作用了鲤看,ip列上的索引是沒有作用的,因?yàn)橹虚g的created列沒有作為查詢條件耍群。

如果既想改變順序义桂,又能利用索引,那還是使用覆蓋索引的方法蹈垢。最佳左前綴法則就是:帶頭大哥不能死澡刹、中間兄弟不能斷。

補(bǔ)充:例如有一個(gè)聯(lián)合索引 idx_nameAgeGender 假如在查詢的時(shí)候三個(gè)字段打亂順序耘婚,是可以用到索引的,因?yàn)閙ysql有自己的優(yōu)化器陆赋。

不在索引列上做任何操作

不在索引列上做任何操作(計(jì)算沐祷、函數(shù)、(自動(dòng)or手動(dòng))類型轉(zhuǎn)換)攒岛,會(huì)導(dǎo)致索引失效而轉(zhuǎn)向全表掃描赖临。

舉例,其中data列是索引列:

EXPLAIN select * from t_logs where left(DATA,4) = 'bcwn'灾锯;

執(zhí)行計(jì)劃:

+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table  | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | t_logs | NULL       | ALL  | NULL          | NULL | NULL    | NULL |  197 |   100.00 | Using where |
+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------------+

范圍條件放最后

存儲(chǔ)引擎不能使用索引中范圍條件右邊的列兢榨。會(huì)導(dǎo)致最后的索引失效。

例子:

EXPLAIN select * from t_logs where action = '訪客訪問' and created < '1528366547' and ip = '58.135.82.57';

導(dǎo)致了ip這列的索引失效了顺饮。

覆蓋索引盡量用

盡量使用覆蓋索引(只訪問索引的查詢(索引列和查詢列一致))吵聪,減少select *的出現(xiàn)。

不等于要甚用

mysql 在使用不等于(!= 或者<>)的時(shí)候無法使用索引會(huì)導(dǎo)致全表掃描兼雄。解決辦法就是使用覆蓋索引吟逝。例子就不舉了,很簡(jiǎn)單赦肋。

Null/Not Null有影響

建表語句:

CREATE TABLE `t_logs` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `action` varchar(100) DEFAULT NULL,
  `data` varchar(100) DEFAULT NULL,
  `author_id` int(10) DEFAULT NULL,
  `ip` varchar(20) DEFAULT NULL,
  `created` int(10) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `actionipcreated` (`action`,`created`,`ip`) USING BTREE,
  KEY `data` (`data`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=938 DEFAULT CHARSET=utf8;

這個(gè)情況有點(diǎn)多块攒,具體取決于該字段是否默認(rèn)為NULL,可以去試試佃乘,遇到這種SQL需要根據(jù)實(shí)際情況去優(yōu)化囱井,索引并不一定會(huì)失效。如果說碰到IS NULLIS NOT NULL一定會(huì)導(dǎo)致索引失效肯定是錯(cuò)了趣避。

Like查詢

like以通配符開頭('%abc...')mysql索引失效會(huì)變成全表掃描的操作庞呕,但不以'%'開頭不會(huì)導(dǎo)致索引失效。

字符類型加引號(hào)

假如一個(gè)列是char或者varchar類型程帕,那么當(dāng)它作為條件的時(shí)候必須加上單引號(hào)千扶,否則會(huì)導(dǎo)致這一列的索引失效料祠。就不舉例子了,也很簡(jiǎn)單澎羞。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末髓绽,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子妆绞,更是在濱河造成了極大的恐慌顺呕,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件括饶,死亡現(xiàn)場(chǎng)離奇詭異株茶,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)图焰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門启盛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人技羔,你說我怎么就攤上這事僵闯。” “怎么了藤滥?”我有些...
    開封第一講書人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵鳖粟,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我拙绊,道長(zhǎng)向图,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任标沪,我火速辦了婚禮榄攀,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘金句。我一直安慰自己航攒,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開白布趴梢。 她就那樣靜靜地躺著漠畜,像睡著了一般。 火紅的嫁衣襯著肌膚如雪坞靶。 梳的紋絲不亂的頭發(fā)上憔狞,一...
    開封第一講書人閱讀 50,050評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音彰阴,去河邊找鬼瘾敢。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的簇抵。 我是一名探鬼主播庆杜,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼碟摆!你這毒婦竟也來了晃财?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤典蜕,失蹤者是張志新(化名)和其女友劉穎断盛,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體愉舔,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡钢猛,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了轩缤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片命迈。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖火的,靈堂內(nèi)的尸體忽然破棺而出壶愤,到底是詐尸還是另有隱情,我是刑警寧澤卫玖,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站踊淳,受9級(jí)特大地震影響假瞬,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜迂尝,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一脱茉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧垄开,春花似錦琴许、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至锻梳,卻和暖如春箭券,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背疑枯。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來泰國(guó)打工辩块, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓废亭,卻偏偏與公主長(zhǎng)得像国章,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子豆村,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351