在查询中过滤“已删除”行的位置

时间:2013-10-16 00:22:49

标签: sql sql-server

我们的数据库中有逻辑删除,每个表都有一个'Deleted'标志,这是一个可以为空的datetime字段。

Deleted DATETIME NULL

在我们的查询中,我使用模式:

SELECT *
FROM TableA a
INNER JOIN TableB b 
   ON b.id = a.pkid
   AND b.deleted IS NULL
INNER JOIN TableC c
   ON c.id = b.pkid
   AND c.deleted IS NULL
WHERE a.deleted IS NULL

这比以下更有效:

SELECT *
FROM TableA a
INNER JOIN TableB b 
   ON b.id = a.pkid
INNER JOIN TableC c
   ON c.id = b.pkid
WHERE a.deleted IS NULL
AND b.deleted IS NULL
AND c.deleted IS NULL

据我所知,当Left连接进入它时,parrent会发生变化。我在这里谈论INNER加入。

我认为第一个更有效,因为服务器执行查询的方式。我找不到我看到的关于阶段的页面...即First the Joins,然后是Where,然后是Order,然后是select ...但是第一个例子会限制数据,然后在哪里被触发,所以WHERE覆盖的数据较少?

1 个答案:

答案 0 :(得分:1)

您还可以将a上的谓词添加到第一个连接...

SELECT *
FROM TableA a
   JOIN TableB b 
      ON b.id = a.pkid
         AND a.deleted IS NULL
         AND b.deleted IS NULL
   JOIN TableC c
      ON c.id = b.pkid
         AND c.deleted IS NULL

但是,一般来说,依靠一种特定的语法方法来产生比另一种更好或更差的性能是不可靠的。查询优化器可以做一些奇怪的事情,通常会将两个截然不同的查询转换为同一个计划。尝试两者并查看查询计划,看看会发生什么。