6

我有两张桌子:

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)运行此查询,那么对于上述条件,运行多个查询或内部联接是否更昂贵(性能方面)?

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

4

4 回答 4

6

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

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

于 2012-06-05T14:04:41.087 回答
3

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

SET showplan on

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

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

EXPLAIN SELECT * FROM some_table

这是使用 Explain 分析查询的教程。

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

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

于 2012-06-05T14:09:48.057 回答
1

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

于 2012-06-05T14:42:52.390 回答
0

为什么不考虑使用外键和级联删除?如果您正确设置表格,您只需删除父级,然后子级就会自动得到照顾。请参阅此链接何时/为什么在 SQL Server 中使用级联?

于 2012-06-05T15:26:21.087 回答