今天遇到一個慢查詢,查詢日誌找到慢查詢語句是這樣的:html
select * from convert_test where areacode=0001 and period>='20170511' and period<='20170511';
convert_test
表結構以下:mysql
CREATE TABLE `convert_test` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `areacode` char(12) NOT NULL DEFAULT '', `period` int(6) unsigned NOT NULL DEFAULT 0, `mid_price` int(10) unsigned NOT NULL DEFAULT 0, `mid_change` float NOT NULL DEFAULT 0, `updated_datetime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `idx_areacode_period` (`areacode`,`period`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='隱式轉換測試表';
表中數據42W以上。git
乍一看,明明建立了一個惟一索引,正常來講,上面的查詢語句應該正好命中idx_areacode_period這個索引的,不該該是慢查詢的。github
爲了查看這個語句是怎麼查詢的,咱們在測試庫中explain一下:sql
mysql> explain select * from convert_test where areacode=0001 and period>='20170511' and period<='20170511';
結果以下:測試
能夠看到,這裏是沒有用到索引的。spa
定義表的時候,areacode字段是字符串類型的,查詢的時候傳入的是0001,這裏0001被Mysql當作了整數處理爲1,Mysql檢測到areacode這個字段的查詢類型是整型,就會全表掃描,將全部行的areacode轉換成整型,而後在作查詢處理。日誌
找緣由了,就很好解決了,上面的sql語句修改以下:code
mysql> explain select * from convert_test where areacode='0001' and period>='20170511' and period<='20170511';
結果以下:htm
能夠看到徹底命中了idx_areacode_period 這個索引。
上面的period定義的時候是整型,可是查詢傳入的是字符串類型,那爲何會命中索引的呢?
看一下官方的隱試轉換說明:
因此,下面的幾個sql語句有相同的效果:
select * from convert_test where areacode=0001 and period>='20170511' and period<='20170511'; select * from convert_test where areacode=1 and period>='20170511' and period<='20170511'; select * from convert_test where areacode=0001.0 and period>='20170511' and period<='20170511'; select * from convert_test where areacode=1.0 and period>='20170511' and period<='20170511';
mysql 在查詢的時候,會將areacode轉換成浮點型進行比較。