我正在尝试优化一个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
现在,我想从表格数据中获取前50个没有条件dbID = 4的条目,并按照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)会导致条目重复多次。
有没有办法改进这个查询?我已经阅读了许多帮助页面和其他问题及其答案,但无法找到这些表的解决方案。