【问题标题】:mysql in clause vs big table joinsmysql in 子句与大表连接
【发布时间】:2015-10-23 12:56:47
【问题描述】:

我有一个查询,它通过加入 3 个大表(每个约 1 毫米记录)来获取数据,此外它们是非常繁忙的表。

做传统连接更好吗?或者更确切地说,首先从第一个表中获取值并执行辅助查询,将检索到的值作为逗号分隔的子句传递?

选项#1

SELECT * 
FROM BigTable1 a
INNER JOIN BigTable2 b using(someField2)
INNER JOIN BigTable3 c using(someField3)
WHERE a.someField1 = 'value'

选项#2

$values = SELECT someField2 FROM WHERE someField1 = 'value'; #(~20-200 values)

SELECT * 
FROM BigTable2
INNER JOIN BigTable3 c using(someField1)
WHERE someField2 in ($values)

选项#3

创建临时表以存储 BigTable1 中的这些值 并使用它而不是直接加入 BigTable1

还有其他选择吗?

【问题讨论】:

  • 毫米是什么计量单位?百万?数百万?谢谢...
  • 取决于行的大小和基数。
  • 您也可以对子查询结果进行连接,但 mysql 的查询优化器可能更喜欢也可能不喜欢。在您的查询中使用EXPLAIN,看看哪个看起来性能更好。比如:SELECT * FROM table1 INNER JOIN (SELECT somefield2 FROM table2 WHERE somefield1 = 'value') as b on table1.f1 = b.f2
  • 谢谢大家,所以我没有明确的答案... :( maythesource.com 每个表都有大约 100 万条记录,第一个子句(值列表)可以在 20-200 之间.

标签: mysql


【解决方案1】:

我认为最好的选择是尝试这两种方法并对其进行解释。 最后,您可以进行的一项优化是为第二种方法使用存储过程,这将减少必须从客户端运行 2 个查询的时间/开销。

最后,连接对于非常大的表来说是一项相当昂贵的操作,因为您实际上是在投影和选择超过 1m X 1m 的行。 (条款:What are projection and selection?

【讨论】:

【解决方案2】:

您的问题没有明确的答案,您可以分析两种方式,因为它们取决于多种因素。

但是,如果所有表都正确索引并且行的大小是“标准的”,则通常采用第一种方法并且应该更快。 还要考虑到,在第二种方法中,网络通信的延迟会更糟,因为您需要多次访问数据库。

【讨论】:

  • 只有在不使用存储过程的情况下,延迟当然是一个问题。此外,他确实提到特定表非常繁忙,这意味着可能需要减少开销。但是,我们都同意他需要对这两种方法进行分析!
猜你喜欢
  • 2021-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-07
相关资源
最近更新 更多