2016-11-09 70 views
0

我有一个大型表,在MySQL数据库中有大约300万条记录。我试图使用以下查询在此表中找到重复行 -如何在多个部分中的大表上查找重复的SQL查询

SELECT package_id 
FROM version 
WHERE metadata IS NOT NULL AND metadata <> '{}' 
GROUP BY package_id, metadata HAVING COUNT(package_id) > 1 

此查询需要〜23秒才能在数据库上运行。然而,我们的数据库主机使用pt-kill杀死任何大于3秒的查询。所以我需要找到一种方法来打破这个查询,比如每个子部分都是一个单独的查询,每个查询的时间少于3秒。只添加一个LIMIT约束不会为查询做到这一点,那么如何中断查询以在表的不同部分上工作。

结果的

SHOW CREATE TABLE version

CREATE TABLE `version` (
    `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, 
    `package_id` bigint(20) unsigned NOT NULL, 
    `version_number` int(11) unsigned NOT NULL, 
    `current_state_id` tinyint(2) unsigned NOT NULL, 
    `md5sum` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_cs NOT NULL DEFAULT '', 
    `uri` varchar(1024) CHARACTER SET utf8 COLLATE utf8_general_cs NOT NULL DEFAULT '', 
    `filename` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_cs NOT NULL DEFAULT '', 
    `size` bigint(11) unsigned NOT NULL DEFAULT '0', 
    `metadata` varchar(1024) CHARACTER SET utf8 COLLATE utf8_general_cs DEFAULT NULL, 
    `storage_type_id` tinyint(2) unsigned NOT NULL DEFAULT '1', 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `idx_version_package_id_version_number` (`package_id`,`version_number`), 
    KEY `idx_version_md5sum` (`md5sum`), 
    KEY `idx_version_metadata` (`metadata`(255)), 
    KEY `idx_version_current_state_id` (`current_state_id`), 
    KEY `storage_type_id` (`storage_type_id`), 
    CONSTRAINT `_fk_version_current_state_id` FOREIGN KEY (`current_state_id`) REFERENCES `state` (`id`), 
    CONSTRAINT `_fk_version_package_id` FOREIGN KEY (`package_id`) REFERENCES `package` (`id`) ON DELETE CASCADE 
) ENGINE=InnoDB AUTO_INCREMENT=3248761 DEFAULT CHARSET=utf8 

如可以看到有上表包括关于字段的package_id + version_number的组合指数许多索引。问题是这张桌子只会变得更大,我不认为优化,即使它在3秒范围内拉回我的比例。所以我需要一种方法来分割这个表并在单独的部分上运行查询。

+0

请发布查询的解释并列出版本表中的索引,并可能描述数据在您的表中的样子。注意:如果目前的服务器在3秒内杀死所有查询,则可能需要切换托管服务提供商的记录数。 – Shadow

+0

你可以添加一个索引到“package_id”吗?那应该是非常快的。 –

+0

发布SHOW CREATE TABLE版本的结果 –

回答

0

提高速度的步骤。

  1. 使用package_id上​​的索引创建Table version_small,其中只有列id和package_id。
  2. insert into version_small select version and package_id from version;
  3. 在上面的优化表上运行原始查询 - 在较小的表上应该快得多。

OR

  1. 只列ID和的package_id,并与package_id与唯一索引的INT计数器version_small创建表。
  2. insert into version_small从版本中选择id和package_id,在重复的key increment counter上;
  3. 计数器> 1的行是包含多个条目的package_id。