我正在尝试优化 SQL 查询以希望提高其执行速度。
我有以下两个表:
CREATE TABLE IF NOT EXISTS `data` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`entry` varchar(255) NOT NULL,
`numDB` int(11) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `entry` (`entry`),
UNIQUE KEY `entry_numDB` (`entry`,`numDB`),
UNIQUE KEY `entry_numDB_id` (`id`,`entry`,`numDB`),
KEY `numDB` (`numDB`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `details` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`dataID` bigint(20) NOT NULL,
`dbID` int(11) NOT NULL,
<removed - unimportant>
PRIMARY KEY (`id`),
KEY `dataID` (`dataID`),
KEY `dbID` (`dbID`),
KEY `dataID_dbID` (`dataID`,`dbID`),
<removed - unimportant>
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
一个条目(例如,'abc')以“id = 1; entry = abc, numDB = 2”的形式存储在表数据中,并且(至少)有两个详细条目“id = 1, dataID = 1, dbID = 4 " 和 "id = 2, dataID = 1, dbID = 17",但是相同的 dataID 和 dbID 可以出现多次,例如,"id = 3, dataID = 1, dbID = 17", "id = 4, dataID = 1,dbID = 17"。
表数据中的
总条目数:45.245.438 表详细信息中的总条目数:126.608.661
现在我想从不具有条件 dbID = 4 的表数据中获取前 50 个条目,按 data.numDB 排序。结果查询是:
SELECT DISTINCT(data.entry), data.numDB FROM blacklists.data data INNER JOIN blacklists.details details ON details.dbID NOT IN (4) AND data.id = details.dataID ORDER BY data.numDB DESC LIMIT 50
这(至少)需要 10 分钟的处理时间(我在 10 分钟后停止了它)。
这是 EXPLAIN 的输出:
EXPLAIN SELECT DISTINCT(data.entry), data.numDB FROM blacklists.data data INNER JOIN blacklists.details details ON details.dbID NOT IN (4) AND data.id = details.dataID ORDER BY data.numDB DESC LIMIT 50
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE data index PRIMARY,entry_numDB_id entry_numDB 261 NULL 45166874 Using index; Using temporary; Using filesort
1 SIMPLE details ref dataID,dbID,dataID_dbID dataID 8 blacklists.data.id 1 Using where; Distinct
不使用 DISTINCT(或 GROUP BY)会导致条目被重复多次。
有没有办法改进这个查询?我已经阅读了许多帮助页面和其他问题及其答案,但无法为这些表格找到解决方案。