查询连接表的子集的有效方法是什么?

时间:2018-04-06 00:57:09

标签: sql sql-server

我的查询有点像这样

SELECT TableA.Column1
FROM TableA 
LEFT JOIN TableB ON TableA.ForeignKey = TableB.PrimaryKey
LEFT JOIN TableC ON TableC.PrimaryKey = TableB.ForeignKey
WHERE TableC.SomeColumn = 'XXX'

在上面的情况中,表A和表B是大表(可能包含超过100万行),但表C很小,只有25行。

我在所有表的主键上应用了索引。

在我们的应用场景中,我需要在TableC中搜索两个条件,TableC.SomeColumn = 'XXX'TableC.SomeColumn = 'YYY'

我的问题是什么是最有效的方法。直接连接确实有效,但我担心在TableB中加入表中的所有行,只是为了选择它的一小部分,在表C中加入。

拥有索引视图是一种好方法吗?

例如,

CREATE INDEXED VIEW FOR TableB 
JOIN TableC ON TableC.PrimaryKey = TableB.ForeignKey
WHERE TableC.SomeColumn IN ('XXX', 'YYY'))? 

2 个答案:

答案 0 :(得分:0)

where子句取消外连接,因此您不妨将查询写为:

SELECT a.Column1
FROM TableA a JOIN
     TableB b
     ON a.ForeignKey = b.PrimaryKey JOIN
     TableC c
     ON c.PrimaryKey = b.ForeignKey
WHERE c.SomeColumn = 'XXX';

对于此查询,您希望索引这些索引:

  • TableC(SomeColumn, PrimaryKey)
  • TableB(ForeignKey, PrimaryKey)
  • TableA(ForeignKey, Column1)

您可以创建索引视图。这通常是查询最快的。但是,更新和插入任何基表可能会产生更多的开销。

答案 1 :(得分:0)

当我需要JOINSELECT数据时,我通常只使用GROUP,而不是在将其用作谓词时。也就是说,我很想知道戈登的答案或者这个答案是否表现得更好。

我还建议在引用表格时养成使用别名的习惯,减少输入,使代码更容易阅读。

我会测试并比较执行时间:

SELECT A.Column1
FROM TableA A
WHERE EXISTS (SELECT 1 
              FROM TableB B
              WHERE A.ForeignKey = B.PrimaryKey
              AND EXISTS (SELECT 1 
                          FROM TableC C
                          WHERE C.PrimaryKey = B.ForeignKey
                          AND C.SomeColumn = 'XXX'))