【问题标题】:Subquery in the WHERE clause in Nonclustered Filtered IndexNonclustered Filtered Index 中 WHERE 子句中的子查询
【发布时间】:2018-04-01 21:06:29
【问题描述】:

我正在使用 SSMS 2016 并尝试在 JOIN 和 Where 条件中使用的两列上创建过滤的非聚集索引。过滤索引时是否允许在 WHERE 子句中使用子查询。下面是对应的例子:

CREATE NONCLUSTERED INDEX [ncIX_MyId_&_EmpId_on_MyDB_Mytbl_optimized] 
ON MyDB.dbo.[Mytbl_Optimized] ([MyId], [EmpId])

WHERE [MyId] IN 
(SELECT DISTINCT Mytbl.[EmpId] FROM MyDB.dbo.Mytbl_Optimized AS t1 (NOLOCK) 
            LEFT OUTER JOIN AnotherDB.dbo.Another-tbl AS t2 WITH (NOLOCK)
            ON t1.EmpId = t2.EmpId)

--The SSMS compiler says incorrect syntax near 'IN'... 

但是当我将子查询替换为显式值时,例如:

WHERE [MyId] IN (1,2) -- it works fine. 

我的目标是提高未编入索引的视图的性能(使该视图编入索引不是一种选择,因为它每 5 分钟更新一次)。在该视图中,上面的 select 语句用作归档结果集:

CREATE VIEW 
AS 
col1,
Col2,
(SELECT DISTINCT Mytbl.[EmpId] FROM MyDB.dbo.Mytbl_Optimized AS t1 (NOLOCK) 
            LEFT OUTER JOIN AnotherDB.dbo.Another-tbl AS t2 WITH (NOLOCK)
            ON t1.EmpId = t2.EmpId 
WHERE AnotherDB.dbo.Table3.MyId = t1.MyId
FOR XML PATH('')) AS MyConcatenatedID
FROM AnotherDB.dbo.Table3 

注意:tbl_Optimized 表的记录总数为 460,000 并且表中唯一 EmpId 值的总数为 26

【问题讨论】:

    标签: sql-server-2012 subquery where-clause non-clustered-index filtered-index


    【解决方案1】:

    除非我误读 this article,否则过滤索引不会帮助您查看。

    另外,我不相信您可以使用子查询来定义索引中包含的内容。根据我的研究和测试,IN 子句中的列表必须是明确的。

    【讨论】:

    • 谢谢布赖恩。我在发布我的问题之前阅读了这篇文章。你是否得到这篇文章的这条语句:“如果过滤索引表达式等同于查询谓词并且查询不返回过滤索引定义中的键或包含列,则过滤索引表达式中的列不需要带有查询结果的过滤索引表达式中的列。” ?
    • 另外,您认为最好只将最不同的列放在索引定义中,将最不不同的列(EmpId)放在 INCLUDE 中以制作 int 覆盖索引?
    • 实际上,我刚刚意识到我不需要为我的过滤索引使用 INCLUDE 选项,因为 EmpID 和 MyId 字段是视图中唯一被选中的字段,它们在JOIN 和 WHERE 子句。并且“包含的列”未存储在索引 B-Tree 中。
    • 抱歉 - 我已经阅读了您引用的五次声明,但我无法理解。我通常喜欢覆盖索引,但每当有人问我“哪个更好?”我给出的唯一答案是“尝试两种方式并比较结果”。
    • Brian,我的声明是我不需要使用覆盖索引,例如; (INCLUDE (EmpId) ) 因为它在 JOIN 和 WHERE 中使用,在其他任何地方都没有。
    猜你喜欢
    • 2014-08-11
    • 2012-10-16
    • 1970-01-01
    • 1970-01-01
    • 2016-07-09
    • 2020-12-31
    • 2011-09-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多