Mysql
精選性能指標
我有一張桌子:
CREATE TABLE `t1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `status` enum('new','paid') NOT NULL DEFAULT 'new', `createdAt` datetime NOT NULL, `updatedAt` datetime NOT NULL, `can_be_closed` tinyint(1) NOT NULL DEFAULT '1', `close_reason` varchar(255) DEFAULT NULL, `interval_before_close` int(11) NOT NULL DEFAULT '10', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
然後選擇:
SELECT `id`, `status`, `close_reason` AS `closeReason`, `createdAt`, `updatedAt` FROM `t1` as t WHERE ( `t`.`status` = 'new' AND `t`.`updatedAt` < '2018-06-22 10:14:36' + INTERVAL `interval_before_close` MINUTE AND `t`.`can_be_closed` = true )
對於此查詢,解釋返回全表掃描。
我嘗試添加以下索引:
ALTER TABLE `t1` ADD INDEX `updatedAt` (`updatedAt` ASC);
和:
ALTER TABLE `t1` ADD INDEX `updatedAt` (`updatedAt` ASC, `interval_before_close` ASC);
但解釋沒有任何變化。
文件前 .:連結
計劃A(不好):
順便說一句,我會說最好先列出
=
列,然後列出一個範圍:INDEX(status, can_be_closed, -- in either order updatedAt) -- last
但是…比這更複雜。
'2018...' + INTERVAL interval_before_close ...
本質上是一個計算日期的函式呼叫。這使得將其中一個
updatedAt
或interval_before_close
放入索引毫無用處。B計劃(懦弱):
所以……以下可能有用,但前提是沒有多少行與這兩個標誌匹配:
INDEX(status, can_be_closed) -- in either order
C計劃(複雜):
另一方面,如果您有一列(實數或計算)包含
updatedAt - INTERVAL interval_before_close MINUTE
說它列被稱為
early_close
; 然後更改為AND early_close < '2018-06-22 10:14:36'
並添加
INDEX(status, can_be_closed, early_close)