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

时间:2015-09-16 23:36:55

标签: mysql hadoop join bigdata spring-xd

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

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

我不确定它是否相关,但我们正在使用spring xd job模块进行其他类型的查询。

我不确定如何对这种作业进行分区,以便它可以并行运行,以便花费更少的时间,因此如果步骤/子部分失败,它可以从它停止的地方继续。

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

这种操作的标准方法是什么,我认为它很常见。我可能会使用错误的搜索词来研究方法,因为我没有遇到任何股票标准解决方案或明确的方向。

相当神秘的原始要求是:

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

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

在表之间使用

AND / OR,然后根据需要执行比较。 SAMPLE1.PARTY_ID和SAMPLE2.PARTY_ID或SAMPLE3.PARTY_ID

我设置了4个测试表,每个测试表都有这个定义

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分钟内完成,桌面尺寸大10倍。 我的测试查询仍然没有完成,并且已经运行了15分钟

1 个答案:

答案 0 :(得分:1)

以下可能的效果优于现有的基于联接的查询:

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(*)条件以匹配要查询的表的数量。

如果要返回任何表中存在的party_id值而不是全部,则省略最后的having子句。