1

我正在从事一个涉及数据集之间连接的项目,我们需要允许预览任意数据集之间的任意连接。这很疯狂,但这就是为什么它很有趣。这是使用面,所以给定一个连接,我想快速显示约 10 行结果。

我一直在围绕不同的方法对不同的表进行子采样,以这样一种方式进行实验,即我至少可以获得一些结果行,但保持样本足够小,以便连接速度快,并且不会导致采样成本高昂。

以下是我发现通过气味测试的方法。我想知道一些关于他们的事情:

  1. 这些会在哪些类型的连接或数据集上失败?
  2. 我如何识别这些数据集?
  3. 如果这两者在同一件事上都不好,那么它们如何改进?
  4. 有没有我没有放在这里的更好的采样类型?

有限制的子选择。

对一个数据集进行随机抽样以减小整体大小。

SELECT col1, col2 FROM table1 JOIN
  (SELECT col1, col2 FROM table2 LIMIT #) AS sample2 
    on table1.col1 = sample2.col1
  LIMIT 10;

我喜欢这个,因为它很容易,并且将来有可能聪明地从哪个表中取样。也可以选择 table1.col1 从不等于 sample2.col1 的部分,因此不返回任何结果。

找到 col1 的相等值并对它们进行采样

更复杂的多查询方法。在这里,我将对要加入的列进行不同的选择,比较结果以找到共同值,然后进行子选择,将结果限制为共同值。

SELECT DISTINCT col1 FROM table1;
SELECT DISTINCT col1 FROM table2;
commonVals = intersection of above results
SELECT col1, col2 FROM table1 JOIN 
  (SELECT col1, col2 FROM table2 WHERE col1 IN(commonVals) LIMIT #) as sample2
    on table1.col1 = sample2.col1 
  LIMIT 10;

这为我们提供了一个很好的 table2 样本,但 select distinct 查询可能比连接更昂贵。如果您知道不同的 cal 需要多长时间,我相信可能有一种方法可以确定这种方法是否更快,但目前我们对数据集的了解不多。

在连接上打一个 LIMIT

这是最简单的,也是我倾向于的。

SELECT col1, col1 FROM table1 join table2 on table1.col1 = table2.col1 LIMIT #

假设连接很好,这将始终返回数据,并且至少在大量情况下它会很快完成。

4

1 回答 1

0

第一种方法的问题是第一个表中的行可能在第二个表中没有匹配项。请记住,内连接不仅进行匹配,还进行过滤。

如果用于连接的所有列都有索引,则第二种方法可以工作。然后,您可以通过执行以下操作获取匹配 id 的列表:

where id in (select id from table1) and id in (select id from table2) . . .

这摆脱了初始代码,应该很快。

第三种方法是最直接地使用数据库的能力。您将取决于 MySQL 根据结果集的大小进行优化的能力。这是它所做的事情,至少在理论上是这样。

我强烈推荐第三种方法与连接中使用的列上的索引结合使用。这需要对查询进行最少的更改(只需添加一个limit子句)。它允许数据库在适当的情况下进行额外的优化。它适用于更一般的查询集。

于 2013-02-22T21:16:44.530 回答