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

时间:2012-06-05 14:02:36

标签: mysql sql-server performance optimization jdbc

我有两张桌子:

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

它们通过 table1.connte table2.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)运行此查询,因此对于上述条件,运行多个查询或内部联接是否更加昂贵(性能明智)?

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

4 个答案:

答案 0 :(得分:6)

在一个查询中执行它可能会更快,而不是两个。您基本上是在尝试自己进行优化,而不是让DBMS这样做,而且通常DBMS'真的很擅长这种东西。

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

答案 1 :(得分:3)

执行此操作的最佳方法是对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分析查询。

总的来说,奥莱克西是正确的;大多数优化器都非常擅长这种事情,并且手动创建临时表并不会对你产生很大影响。很多时候,优化器的查询计划将涉及创建临时表。

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

答案 2 :(得分:1)

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

答案 3 :(得分:0)

为什么不考虑使用外键和级联删除?如果您正确设置了表格,则只需删除父项,然后孩子就会自动得到处理。请参阅此链接When/Why to use Cascading in SQL Server?