【问题标题】:Can a query use more than one nonclustered index for a table?一个查询可以为一张表使用多个非聚集索引吗?
【发布时间】:2011-08-13 02:52:24
【问题描述】:

我有一个看起来像这样的查询

SELECT TOP 1000 C.iId_company
FROM dbo.Company AS C WITH(NOLOCK)
WHERE 
C.col_1 LIKE 'something%'
OR C.col_1 LIKE 'something2%'
OR C.col_1 LIKE 'something3%'
OR C.col_2 LIKE 'something%'
OR C.col_2 LIKE 'something2%'
OR C.col_2 LIKE 'something3%'

我尝试加快查询速度,并尝试在 col_1 和 col_2 上添加索引。如果我注释掉有关 col_2 的条件,则查询速度非常快,对于 col_1 也是如此(如果我注释掉有关 col_1 的条件)。但是当我就这样离开时,它又是一个老故事,非常缓慢。

我从执行计划中怀疑,一次只使用一个索引,SQL 在使用第一个索引后执行子集扫描。我尝试了不同的方法(为两列创建索引,但也不起作用)

实际上,我唯一的解决方案是拆分查询并使用 UNION。有没有办法让这种查询更快并保留在一个查询中?

【问题讨论】:

  • 如果您尝试OPTION (FORCESEEK) 提示会怎样?那会做一个索引联合吗?
  • @Martin 在这种情况下你不能只为两列创建索引吗?
  • @rsbarro。如果他们创建了一个复合索引col1,col2col2,col1,则只能分别为col_1 LIKE 'something%'col_2 LIKE 'something%' 寻找它。它仍然需要扫描整个索引以确定其他OR-ed 标准。
  • @Martin 我明白了。我猜如果将它们组合在一起,复合索引会有所帮助,对吧?
  • @rsbarro 我认为你是对的,使用 AND 会导致使用复合索引,因为查询将匹配索引的组成,然后通过它进行搜索。

标签: sql sql-server sql-server-2008 indexing


【解决方案1】:

您的要求指出需要两个单独的索引,在您搜索的每一列上都有一个。使用您喜欢的任何 DBA 工具来生成和查看查询的解释计划。现在您可以开始重新处理查询,以查看解释计划是否比您之前的尝试更好。您可能需要使用 UNION 或公用表表达式将两个查询组合成一个结果集。

【讨论】:

    【解决方案2】:

    使用联合。那就是:

    SELECT TOP 1000 C.iId_company
    FROM dbo.Company AS C WITH(NOLOCK)
    WHERE 
    C.col_1 LIKE 'something%'
    OR C.col_1 LIKE 'something2%'
    OR C.col_1 LIKE 'something3%'
    
    union all 
    
    SELECT TOP 1000 C.iId_company
    FROM dbo.Company AS C WITH(NOLOCK)
    WHERE 
    C.col_2 LIKE 'something%'
    OR C.col_2 LIKE 'something2%'
    OR C.col_2 LIKE 'something3%'
    

    根据需要进行调整(例如,您可能需要将整个内容包装在一个 select 中,以便您可以添加一个 order by 子句来获得您认为是前 1000 个的内容)。但我认为您会对这个解决方案感到满意。

    【讨论】:

    • 使用 UNION ALL 来附加两个结果集可能会产生重复的行,因此最终从此联合中选择的表达式将需要发出 SELECT DISTINCT,或者上面的查询可以使用 UNION 和引发该级别的排序。
    • 这就是我试图避免的。我已经能够生成该查询。 (我问题的最后一行)
    • @Fred:你是对的。我认为从集合中获取前 1000 名在从联合中选择时会比在联合中执行不同的方式稍微更有效率。
    • @MaxiWheat:这就是你如何让它使用多个索引。问问自己,性能还是可维护性对您来说更重要。
    猜你喜欢
    • 2011-06-04
    • 2014-11-04
    • 2012-08-05
    • 2012-08-26
    • 2011-04-17
    • 1970-01-01
    • 2011-08-21
    • 1970-01-01
    • 2021-10-28
    相关资源
    最近更新 更多