Mysql
解釋不顯示索引列作為鍵
考慮下面的表結構
CREATE TABLE `games` ( `game_id` bigint(20) NOT NULL AUTO_INCREMENT, `players_no` tinyint(4) DEFAULT NULL, `startedon` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `game_type` enum('R','C') NOT NULL DEFAULT 'R', `expirydatetime` datetime NOT NULL, `users_info` text NOT NULL, `lastupdate` datetime NOT NULL, `count_temp_user` int(1) NOT NULL DEFAULT '0', `msg_pid` varchar(3) NOT NULL, PRIMARY KEY (`game_id`), KEY `startedon` (`startedon`), ) ENGINE=InnoDB AUTO_INCREMENT=11009966 DEFAULT CHARSET=utf8
現在,考慮以下查詢
SELECT * FROM `games` WHERE DATE(games.expirydatetime)<CURDATE() AND `players_no` = 2
當我解釋上述查詢時,我得到以下結果
id|select_type|table|type|possible_keys|key |key_len|ref|rows|filtered|Extra 1 |SIMPLE |games|ALL |NULL |NULL|NULL|NULL|314|100.00|Using where
如果我在 expirydatetime 上添加索引,在解釋後我仍然看不到
expirydate
key 列。對此行為有任何解釋嗎?是因為 expirydatetime 是在 mysql 內置函式中使用的嗎?mysql還會考慮expirydatetime的索引嗎?
首先,顯示 null 是因為子句
possible_keys
中使用的兩列中的任何一列都沒有索引。WHERE
因此,對於這個查詢,甚至沒有有用的索引可以考慮。但是即使在 上添加索引
(expirydatetime)
,情況仍然不好。因為當您在條件中的函式內放置一列時,例如DATE(games.expirydatetime)<CURDATE()
,您基本上是在禁止使用索引。雖然可能可以在列上使用索引,但它仍然必須執行完整的索引掃描(因為使用了函式),然後訪問表中匹配的行。因此優化器選擇進行表掃描。要使查詢使用索引並更高效,請將條件更改為:
WHERE expirydatetime < CURDATE() AND players_no = 2
並添加一個複合索引
(players_no, expirydatetime)