对非常大的 INNER JOIN SQL 查询进行分区

Partition a very large INNER JOIN SQL query

sql 查询是相当标准的内部联接类型。 例如,比较 n tables 以查看所有 n tables 中存在哪些 customerId 将是一个基本的 WHERE ... AND 类型查询。

问题是 table 的大小超过 1000 万条记录。数据库是非规范化的。规范化不是一种选择。 查询要么需要很长时间才能完成,要么永远不会完成。

我不确定它是否相关,但我们正在使用 spring xd 作业模块来处理其他类型的查询。

我不确定如何划分此类作业,以便它可以 运行 并行进行,这样花费的时间更少,因此如果 step/subsection 失败,它可以从哪里继续它停止了。

其他有类似问题的帖子建议使用数据库引擎以外的替代方法,例如在代码中实现 LOOP JOIN 或使用 MapReduce 或 Hadoop,我从未使用过它们,我不确定它们是否值得研究这个用例。

这种操作的标准方法是什么,我希望它相当普遍。我可能使用了错误的搜索词来研究方法,因为我没有遇到任何常用的标准解决方案或明确的方向。

相当神秘的原始要求是:

比较三个非常大的 table 中的 party_id 列以确定三个 table 中可用的客户 即如果它是三个之间的 AND 操作。 SAMPLE1.PARTY_ID 和 SAMPLE2.PARTY_ID 和 SAMPLE3.PARTY_ID

如果操作是 OR,则选择三个 table 中的所有可用客户。 SAMPLE1.PARTY_ID 或 SAMPLE2.PARTY_ID 或 SAMPLE3.PARTY_ID

AND / OR 在 table 之间使用,然后根据需要进行比较。 SAMPLE1.PARTY_ID 和 SAMPLE2.PARTY_ID 或 SAMPLE3.PARTY_ID

我设置了一些 4 个测试 table,每个测试都具有这个定义

CREATE TABLE `TABLE1` (
  `CREATED` datetime DEFAULT NULL,
  `PARTY_ID` varchar(45) NOT NULL,
  `GROUP_ID` varchar(45) NOT NULL,
  `SEQUENCE_ID` int(11) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`SEQUENCE_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=978536 DEFAULT CHARSET=latin1;

然后将 1,000,000 条记录添加到应该导致连接的范围内的每个随机数字。

我使用了以下测试查询

SELECT `TABLE1`.`PARTY_ID` AS `pi1`, `TABLE2`.`PARTY_ID` AS `pi2`, `TABLE3`.`PARTY_ID` AS `pi3`, `TABLE4`.`PARTY_ID` AS `pi4` FROM `devt1`.`TABLE2` AS `TABLE2`, `devt1`.`TABLE1` AS `TABLE1`, `devt1`.`TABLE3` AS `TABLE3`, `devt1`.`TABLE4` AS `TABLE4` WHERE `TABLE2`.`PARTY_ID` = `TABLE1`.`PARTY_ID` AND `TABLE3`.`PARTY_ID` = `TABLE2`.`PARTY_ID` AND `TABLE4`.`PARTY_ID` = `TABLE3`.`PARTY_ID`

它应该在 10 分钟内完成,table 尺寸要大 10 倍。 我的测试查询仍未完成,已经 运行ning 了 15 分钟

以下可能比现有的基于连接的查询执行得更好:

select party_id from
(select distinct party_id from SAMPLE1 union all
 select distinct party_id from SAMPLE2 union all
 select distinct party_id from SAMPLE3) as ilv
group by party_id 
having count(*) = 3

修改 count(*) 条件以匹配正在查询的 table 的数量。

如果您想要 return party_id 存在于 any table 中的值而不是全部,则省略最后的 having 子句。