什么时候最好不要使用内连接?

Posted

技术标签:

【中文标题】什么时候最好不要使用内连接?【英文标题】:When is it better not to use inner join? 【发布时间】:2012-06-09 13:23:26 【问题描述】:

我有两张桌子:

table1 (id, name, connte)
table2 (id, name, connte)

它们通过table1.conntetable2.connte连接。每条记录包含 100 条记录。

现在,如果我想从 table1 中删除一条 id = 20 的记录及其在 table2 中的相应子项,最好执行以下操作:

   DELETE d1,d2 FROM table1 d1 INNER JOIN table2 d2 ON d1.connte= d2.connte WHERE d1.id = 20

或以下:

  select connte from table1 where id = 20
  --Store connte in a variable say aabc--
  delete from table2 where connte = aabc   -> execute this first
  delete from table1 where id = 20    -> execute this second

如果我要删除的记录只有一个父级和一个子级(此处 table1.id =20),那么对整个表进行内连接不是很昂贵吗?

我正在从 JAVA(所以 JDBC)运行此查询,那么对于上述条件,运行多个查询或内部联接是否更昂贵(性能方面)?

注意:假设表没有参照完整性。所以,我没有使用级联删除。

【问题讨论】:

【参考方案1】:

最好的方法是对 DBMS 中的两个查询都运行一个解释计划,输出会为您提供 I/O 估计等信息。一般来说,只要您有关于什么会更有效的问题从 DBMS 的角度来看,查看查询计划和成本估算是您最好的武器。

SET showplan on

应该在 SQL Server 中工作。这是MSDN documentation,您可能需要稍微不同的语法,具体取决于您的 DBMS。 I/O 成本估算可能是您最关心的。

对于mysql,看起来你可以使用

EXPLAIN SELECT * FROM some_table

Here is a tutorial 关于使用 Explain 分析查询。

总的来说,Oleksi 是正确的;大多数优化器都非常擅长这种事情,手动创建临时表不会给你带来太多好处。很多时候优化器的查询计划会涉及到创建一个临时表。

对于删除查询,要确保速度的一件重要事情是您的删除子句使用索引参数,因此不会导致全表扫描。 Explain/Showplan 将告诉您查询正在执行哪种类型的扫描,以及它正在使用哪些索引。您通常希望避免全表扫描。

【讨论】:

【参考方案2】:

为什么不考虑使用外键和级联删除?如果你正确地设置了你的表,你只需要删除父级,然后子级就会自动得到照顾。看这个链接When/Why to use Cascading in SQL Server?

【讨论】:

【参考方案3】:

在 Sql Server 中,您不能在一个删除语句中从两个表中删除(没有触发器或级联删除)。

【讨论】:

那么,在我的情况下(没有参照完整性和触发器),只有第二个条件是可能的?【参考方案4】:

在一个查询中完成它可能会更快,而不是两个。您基本上是在尝试自己进行优化,而不是让 DBMS 来做,通常 DBMS 非常擅长这类事情。

此外,您可能不必担心这么小的表的删除性能。 100 x 100 行仍然非常小,因此您的 DBMS 应该能够毫无问题地处理这个问题。

【讨论】:

嗯..好的,但是当我有十万或一百万条记录时呢?那么哪种方法更适合我提到的情况? 我仍然建议让 DBMS 处理它。它比你可能知道如何更好地进行这些优化。 有什么方法可以知道内部连接的工作原理吗?不会加入两个表,每个表都有数百万条记录,需要时间吗? (即使用ON子句过滤后,也有可能要加入的记录很多) @Harke,如果您要删除数百万条记录,无论如何您都希望分批执行此操作。如果索引正确,连接速度很快。 DBMS 通常选择以不会导致大量中间结果记录的方式进行连接。正如其他答案中提到的,您可以通过使用showplan 确切地看到执行了什么样的连接

以上是关于什么时候最好不要使用内连接?的主要内容,如果未能解决你的问题,请参考以下文章

为啥叫内连接和外连接?

sql 各种连接的使用条件,

sqlServer 2005 中内连接(inner join)与左连接(left join)的区别?最好附加个实例?

sql查询:使用内连接查询两张表的时候,如果左边表的一条记录对应了右边表的两条记录,结果显示排列问题

java 事务

详解SQL Server连接(内连接外连接交叉连接)