什么是更快删除哪里或删除子查询在哪里?

时间:2014-10-13 15:10:51

标签: sql postgresql

我在项目中找到了代码的和平

delete from queue where id in(
   select id
   from queue
   where date_part('day', now() - date_of_sending) >= 40)

我认为这种变体更好

delete from queue where date_part('day', now() - date_of_sending) >= 40

当然服务器会优化它们,但哪个查询更快?

4 个答案:

答案 0 :(得分:1)

只有数据库引擎本身可以告诉你哪一个会更快地执行(或者根本不会执行任何差异)。

然而,第一个显然是不必要的复杂,因此第二个是首选。

答案 1 :(得分:1)

这个问题不仅仅 关于查询速度,而将子查询合并到原始语句中是否逻辑正确。

首先,您在此处使用唯一的关系queue。因此,列iddate_of_sending属于同一个关系。所以这意味着你的陈述:

DELETE FROM queue WHERE date_part('day', now() - date_of_sending) >= 40

与子查询的逻辑等效,你可以使用它。

但这不会让你的查询更快。

您正在使用列date_of_sending作为函数调用的一部分。因此,要使DBMS能够使用此构造的索引,您必须在整个表达式上构建function-based index。要避免此限制并在列上使用可能的索引,请重写(并简化)WHERE子句,如下所示:

DELETE FROM queue WHERE date_of_sending >= current_date-40;

考虑可能的优化,总是很好的检查是否有任何带有列的表达式并尝试以这种方式重写它们,该列以自由形式使用 - 这为规划者使用索引提供了更多的自由。 / p>

是的,正如评论中所建议的,EXPLAIN (analyze, buffers)是你的朋友 请注意,这实际上会执行您的DELETE声明。因此,您最好将整个内容包装到显式事务中:

BEGIN;
EXPLAIN (analyze, buffers)
  DELETE FROM queue WHERE id IN (
    SELECT id FROM queue
     WHERE date_part('day', now() - date_of_sending) >= 40);
EXPLAIN (analyze, buffers)
  DELETE FROM queue WHERE date_of_sending >= current_date-40;
ABORT;

答案 2 :(得分:0)

WhereInnerquery更快。在内部查询案例中,首先会触发,然后主要查询才会运行。但是如果只过滤那些包含where条件的行并且只删除那些记录的行。

答案 3 :(得分:0)

警告,对于第一个,您将收到MySQL的错误:#1093 - 您无法在FROM子句中为更新指定目标表'queue'。但第二个无处不在。