具有相同列的多个索引建议

Multiple index suggestions with same columns

我有一个 table 每小时收到数千个 select 查询。 SQL 服务器建议我创建四个索引,每个索引估计有 99% 的改进:

类型如下:

table 没有更新那么频繁,select 查询似乎超过 updates/inserts 大约 1000 比 1。那么问题是,我应该创建所有索引还是创建一个索引有助于改善所有查询?如果我想一次添加一个,并在每次添加后检查性能,我应该按什么顺序添加它们,应该单独添加还是组合添加?如果问题无法回答,除了反复试验之外,我还能做些什么来找出答案,这不是一种选择,因为我自己无法修改这些。

编辑(建议链接到索引的查询):

查询 1:

SELECT  TOP (1) 
    * --enumerated, but still all columns selected
FROM
    "TableName" WITH(UPDLOCK)  
WHERE 
    ("Line Code"=@0 AND "Code Qualifier"=@1 AND "Line No_"=@2)
ORDER BY 
    "Message Batch Number" ASC,
    "Message Line Number" ASC OPTION(OPTIMIZE FOR UNKNOWN)

查询 2:

SELECT 
    * --enumerated, but still all columns selected
FROM 
    "TableName" WITH(UPDLOCK)
WHERE 
    ("Line Code"=@0 AND "Code Qualifier"=@1 AND "Status"=@2 AND "Line No_"=@3) 
ORDER BY 
    "Message Batch Number" ASC,
    "Message Line Number" ASC OPTION(OPTIMIZE FOR UNKNOWN, FAST 50)

查询 3:

UPDATE 
    "TableName" 
SET 
    "Status"=@0 
WHERE ("Code Qualifier"=@1)

因此,其中一个实际上是更新。这也每小时执行多次,但不像 select 那样频繁。我无法立即找到这些查询之一,但希望这些可以。

编辑 2(现有索引): 所以这些已经到位,但几乎没有在任何查询中使用:

孤立地查看查询,理想情况下您需要以下索引:

查询 1

CLUSTERED INDEX ([Line Code], [Code Qualifier], [Line No_],
  [Message Batch Number], [Message Line Number])
-- first three columns in any order

查询 2

CLUSTERED INDEX ([Line Code], [Code Qualifier], [Line No_], Status,
  [Message Batch Number], [Message Line Number])
-- first four columns in any order

前几列的顺序应该是最有选择性的。

您可以通过删除 Status 来合并前两个索引。缺点是它不能被查找,但因为它是一个聚集索引,所以不会那么重要。如果你想要一个非聚集索引,那么 all 其他选定的列应该在 INCLUDE.

所以最终需要的索引是:

CLUSTERED INDEX ([Line Code], [Code Qualifier], [Line No_],
  [Message Batch Number], [Message Line Number])
-- first three columns in any order

-- you can change it to NONCLUSTERED by using INCLUDE
NONCLUSTERED INDEX ([Line Code], [Code Qualifier], [Line No_],
  [Message Batch Number], [Message Line Number])
  INCLUDE (Status, anyOtherColumnsHere)

对于查询 3 你只需要,

NONCLUSTERED INDEX ([Code Qualifier]) INCLUDE (Status)

如果您使用的是诸如 Linq2SQL 之类的 ORM(给定参数名称,这似乎是这样),请确保传入正确的变量数据类型和长度,否则将不会使用索引

我设法通过复制我们的生产数据库来测试这个,运行 这些查询在有和没有不同索引的循环中。令人惊讶的是,似乎只在 Code Qualifier 上添加非聚集索引可以将所有查询的执行时间降低到几乎为零,并进行几十次迭代。因此,在回答我自己的问题时,单个列的单个索引似乎足以满足实际目的。