我应该添加多个二级索引进行搜索

时间:2013-12-27 17:27:03

标签: sql sql-server performance

我的应用上有一个搜索屏幕,用户最多可以使用4个参数进行搜索。我编写了一个存储过程以方便搜索。

Select 
    ID,
    FirstName,
    LastName,
    CountryCd,
    State,
    Zip,
    Data1,
    Data2,
    Data3
From 
    Customer
Where 
    ((FirstName like @paramfname) OR (@paramfname IS NULL) )
    AND ((LastName like @paramlname) OR (@paramlname IS NULL))
    AND CountryCd = @paramcountry
    AND ((Zip = @paramzip) OR  (@paramzip IS NULL))

我添加了一个包含所有4列FirstName,LastName,CountryCdZip的二级索引。

CREATE NONCLUSTERED INDEX [idx_Cust_FN_Ctry] 
ON [dbo].[Customer]([FirstName] ASC, [LastName] ASC, [CountryCd] ASC, [Zip] ASC)

我的问题:这个指数足以进行有效搜索吗?如果用户仅使用FirstNameCountry运行搜索,SQL Server是否知道如何有效地使用索引?

或者我是否需要在每个字段上添加4个单独的二级索引?

由于

3 个答案:

答案 0 :(得分:0)

如果用户按名字和国家搜索而不是索引,那么最有可能是有益的。但是,如果用户通过搜索仅使用姓氏,则必须完全读取索引 - 索引扫描。

请注意,索引键列顺序很重要,因为它告诉SQL Server如何对索引进行逻辑排序。在设计索引及其关键列时

([FirstName] ASC,[LastName] ASC,[CountryCd] ASC,[Zip] ASC)

你应该从最具选择性的一开始。在这种情况下,我相信将是姓氏。我写了一篇关于这个主题的博客文章:http://sqlmate.wordpress.com/2013/11/05/interview-question-2/

在某些情况下,需要添加多个索引来支持读取。但要注意不要过度索引:)

答案 1 :(得分:0)

对于此查询,我将使用CountryCd引导索引,因为这是唯一可以保证搜索的列。这当然假设CountryCd的选择性对您的数据具有选择性。

如果你想变得非常花哨,你可以添加一个包含SOUNDEX FirstName和另一个LastName的计算列并对其进行索引。如果您这样做,您可以像这样表达过滤器

((FirstNameSound = SOUNDEX(@paramfname)) OR (@paramfname IS NULL) )
AND ((LastNameSound = SOUNDEX(@paramlname) OR (@paramlname IS NULL))
AND CountryCd = @paramcountry
AND ((Zip = @paramzip) OR  (@paramzip IS NULL))

这仅适用于英语发音名称 - 在执行此操作之前,您应该了解SOUNDEX功能的含义。

关于1-4个索引的问题:这实际上取决于通常一起搜索的内容。如果任何组合同样可能,您可能需要所有四个索引(或者至少是选择性列的索引)。如果通常一起搜索FirstNameLastName,则应该在这两列上有索引。

然而,让我挑战你的设计。看起来你正试图解决传统索引的全文索引问题。我建议在最终确定设计之前查看SQL Server中的全文索引引擎。

答案 2 :(得分:0)

我会使用动态sql并消除任何null参数的搜索条件,并消除所有的慢速或子句。它们可能会导致优化跳过有用的索引。