為什么我加了索引,SQL執行還是這么慢(一)?


在MySQL中,有一些語句即使邏輯相同,執行起來的性能差異確實極大的。

先拋出一個結論:如果想使用索引樹搜索功能,就不能使用數據庫函數來處理索引字段值,而是在不改變索引字段值的同時,自己通過SQL語句來實現邏輯

條件字段函數操作

假設我們現在維護了一張系統交易表:

mysql> CREATE TABLE `tradelog` (
  `id` int(11) NOT NULL,
  `tradeid` varchar(32) DEFAULT NULL,
  `operator` int(11) DEFAULT NULL,
  `t_modified` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `tradeid` (`tradeid`),
  KEY `t_modified` (`t_modified`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

我們在表中插入5條測試數據:

insert into tradelog (id,tradeid,t_modified) values(1,'a','2017-03-15');
insert into tradelog (id,tradeid,t_modified) values(2,'b','2017-06-11');
insert into tradelog (id,tradeid,t_modified) values(3,'c','2017-07-03');
insert into tradelog (id,tradeid,t_modified) values(4,'d','2018-08-11');
insert into tradelog (id,tradeid,t_modified) values(5,'e','2018-09-12');

 

 SQL執行結果

接下來我們需要查詢2016年到2018年,所有7月份的數據。

SQL可以這樣寫:

select count(*) from tradelog where month(t_modified)=7;

我們可以通過explain命令,對這行語句的執行結果進行分析。

SQL執行結果

即該語句使用了t_modified索引,row=5,代表了該語句進行了全索引掃描,Using index表示使用了覆蓋索引。

那么為什么會這樣呢?

首先執行操作用哪個索引,是優化器決定的,這里可以使用的索引是主鍵索引和t_modified索引。在對比索引樹大小后發現,t_modified索引樹更小,所以優化器選擇使用t_modified索引,但是為什么還會使用全索引掃描,而不是索引樹查找的方式呢?原因是innodb索引樹查找的方式,是由於同級的兄弟節點具有順序性(類似於二分查找,要求數據有序),鎖索引值的順序性被破壞,優化器就只能選擇全索引掃描的方式執行語句,所以

對索引字段的函數操作,會破壞索引值的順序性,導致優化器放棄走索引樹搜索功能。

我們如果想使用索引樹搜索功能,就不能使用數據庫函數來處理索引字段值,而是在不改變索引字段值的同時,自己通過SQL語句來實現邏輯,上述SQL語句可做如下的改寫:

select count(*) from tradelog where
(t_modified >= '2016-7-1' and t_modified<'2016-8-1') or
(t_modified >= '2017-7-1' and t_modified<'2017-8-1') or 
(t_modified >= '2018-7-1' and t_modified<'2018-8-1');

接着我們使用explain對其進行分析:

 

 SQL執行結果

此時我們可以看出,此時該語句采用了樹搜索的方式,只掃描了3行數據。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM