Mysql

精選性能指標

  • June 22, 2018

我有一張桌子:

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 ...

本質上是一個計算日期的函式呼叫。這使得將其中一個updatedAtinterval_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)

引用自:https://dba.stackexchange.com/questions/210335