經常被問,NOT IN和<>操作就無法走索引?
真想只有一個:具體問題具體分析,沒有前提的問題都是耍流氓。
准備測試數據:
## 刪除測試表 DROP TABLE IF EXISTS tb2001; ## 創建測試表 CREATE TABLE `tb2001` ( `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, `c1` int(11) DEFAULT NULL, `c2` int(11) DEFAULT NULL, INDEX idx_c1(c1) ) ENGINE = InnoDB CHARSET = utf8; ## 插入測試數據(10萬左右) ## 如果information_schema.columns數據較少,可以重復多次 INSERT INTO tb2001 (c1,c2) SELECT 1,1 from information_schema.columns; INSERT INTO tb2001 (c1,c2) SELECT 2,2 from information_schema.columns limit 10;
INSERT INTO tb2001 (c1,c2)
SELECT 3,3 from information_schema.columns limit 10;
表中tb2001上C1列上有索引,全表數據10萬條,但c1<>1的數據僅為20條。
查詢c1不為1的10條數據,NOT IN 方式執行計划為:
desc select * from tb2001 where c1 not in(1) limit 10 \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: tb2001 partitions: NULL type: range possible_keys: idx_c1 key: idx_c1 key_len: 5 ref: NULL rows: 11 filtered: 100.00 Extra: Using index condition
查詢c1不為1的10條數據,<>方式執行計划為:
desc select * from tb2001 where c1 <> 1 limit 10 \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: tb2001 partitions: NULL type: range possible_keys: idx_c1 key: idx_c1 key_len: 5 ref: NULL rows: 11 filtered: 100.00 Extra: Using index condition
從上面兩個例子可以看出,NOT INT和<>操作都可以走索引,且執行性能極佳。
俗話說蒼蠅不叮無縫的丹,因為在很多場景下,NOT IN或<>兩類操作使用二級索引的成本遠超於全表掃描的成本,查詢優化器按照成本選擇"最優執行計划",導致查詢不走二級索引。但不能因此就徹底判斷NOT IN或<>兩類操作不能走索引。