【发布时间】:2015-12-10 09:49:00
【问题描述】:
我在优化 SQL 中的某个查询时遇到了一些问题(使用 MariaDB),为您提供一些上下文:我有一个带有“事件”(将它们视为日志条目)的系统,可以在票证上发生,也可以在除了门票之外的其他一些对象(这就是我将 event 和 ticket_event 表分开的原因)。我想按 display_time 排序所有ticket_events。事件表现在有大约 2000 万行。
CREATE TABLE IF NOT EXISTS `event` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`type` varchar(255) DEFAULT NULL,
`data` text,
`display_time` datetime DEFAULT NULL,
`created_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `index_for_display_time_and_id` (`id`,`display_time`),
KEY `index_for_display_time` (`display_time`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `ticket_event` (
`id` int(11) NOT NULL,
`ticket_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `ticket_id` (`ticket_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `ticket_event`
ADD CONSTRAINT `ticket_event_ibfk_1` FOREIGN KEY (`id`) REFERENCES `event` (`id`),
ADD CONSTRAINT `ticket_event_ibfk_2` FOREIGN KEY (`ticket_id`) REFERENCES `ticket` (`id`);
如您所见,我已经使用了一些键(我还为 (id, ticket_id) 制作了一个,因为我再次删除了它,所以现在这里没有显示)我执行的查询:
SELECT * FROM ticket_event
INNER JOIN event ON event.id = ticket_event.id
ORDER BY display_time DESC
LIMIT 25
该查询需要相当长的时间来执行(如果我过滤特定的ticket_id,大约需要30s,如果不过滤它甚至无法可靠地完成它)。如果我对查询运行解释,它显示它执行文件排序 + 临时:
我玩了一下力指数等,但这似乎没有解决任何问题,或者我做错了。
有没有人看到我做错了什么或者我可以在这里优化什么?我非常不希望通过添加ticket_id/host_id 等作为列来使“事件”成为一个宽表,如果它们不适用则将它们设为NULL。
提前致谢!
【问题讨论】:
标签: mysql sql query-optimization mariadb