我有一个包含大约 10 万行的表(日志)。每行都有一个与其创建时间关联的时间戳。当我按此时间戳排序时,即使有许多 WHERE 条件,查询也比没有排序慢得多。我似乎找不到加快速度的方法。我尝试了各种索引。
查询返回大约 25k 行。我有类似的查询需要运行,但 WHERE 标准略有不同。
使用 ORDER BY,查询需要 0.6 秒。如果没有 ORDER BY,查询需要 0.003 秒。
表结构如下。
CREATE TABLE IF NOT EXISTS `logs` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`shipment_id` int(11) DEFAULT NULL,
`time` timestamp NULL DEFAULT NULL,
`initials` varchar(50) DEFAULT NULL,
`result` int(11) DEFAULT NULL,
`information` int(11) DEFAULT NULL,
`issues` varchar(5) DEFAULT NULL,
`fw_actions` varchar(999) DEFAULT NULL,
`noncompliant` tinyint(4) DEFAULT NULL,
`noncompliant_lead_initials` varchar(50) DEFAULT NULL,
`noncompliant_lead_time` varchar(20) DEFAULT NULL,
`event_id` int(11) DEFAULT NULL,
`action_id` int(11) DEFAULT NULL,
`resolution_id` int(11) DEFAULT NULL,
`noncompliant_reviewed` tinyint(4) NOT NULL DEFAULT '0',
`violation` tinyint(4) DEFAULT NULL,
`approved` tinyint(4) NOT NULL DEFAULT '0',
`approved_time` timestamp NULL DEFAULT NULL,
`approver` int(11) DEFAULT NULL,
`reviewed` tinyint(4) NOT NULL DEFAULT '0',
`reviewed_time` timestamp NULL DEFAULT NULL,
`reviewer` int(11) DEFAULT NULL,
`editor` int(11) DEFAULT NULL,
`summary` varchar(999) DEFAULT NULL,
`updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `LOGS_SHIPMENT_ID_TIME` (`shipment_id`,`time`,`action_id`),
KEY `SHIPMENT_ID_IDX` (`shipment_id`),
KEY `logs_updated_index` (`updated`),
KEY `violation_idx` (`violation`,`approved`,`reviewed`,`shipment_id`,`time`,`reviewer`,`approver`,`editor`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=100022 ;
查询是
SELECT * FROM logs
WHERE (logs.approved != 1) AND (logs.violation = 1)
ORDER BY logs.`time` DESC
我的 EXPLAIN 看起来像这样
id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE logs ref violation_idx violation_idx 2 const 1000 Using index condition; Using where; Using filesort
这里有人有技巧吗?谢谢!
最佳答案
key_len 列表示 MySQL 仅使用索引“violation_idx”的 2 个字节。所以它只使用前两列,“violation”和“approved”,每一列都是一个 tinyint(一个字节)。
您可能可以通过使“时间”成为该索引中的第三列来提高该查询的性能。目前,它是第五列。我不知道你在做什么其他查询;这种更改可能会损害其他查询的性能。
另外,您可能可以通过单独在“time”列上创建一个额外的索引来提高性能。这两件事都值得测试。
大多数 dbms 将受益于对“时间”进行降序排序的索引,但是 MySQL won't .
An index_col_name specification can end with ASC or DESC. These keywords are permitted for future extensions for specifying ascending or descending index value storage. Currently, they are parsed but ignored; index values are always stored in ascending order.
您必须找到自己的舒适度。今天,创建索引“DESC”清楚地表达了您的意图,但 future 升级到开始解析和实现该表达式的 MySQL 可能会损害其他查询的性能。
关于mysql - 由于时间戳顺序查询缓慢,无法弄清楚如何解决,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23597141/