我的应用上有一个搜索屏幕,用户最多可以使用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,CountryCd
和Zip
的二级索引。
CREATE NONCLUSTERED INDEX [idx_Cust_FN_Ctry]
ON [dbo].[Customer]([FirstName] ASC, [LastName] ASC, [CountryCd] ASC, [Zip] ASC)
我的问题:这个指数足以进行有效搜索吗?如果用户仅使用FirstName
和Country
运行搜索,SQL Server是否知道如何有效地使用索引?
或者我是否需要在每个字段上添加4个单独的二级索引?
由于
答案 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个索引的问题:这实际上取决于通常一起搜索的内容。如果任何组合同样可能,您可能需要所有四个索引(或者至少是选择性列的索引)。如果通常一起搜索FirstName
加LastName
,则应该在这两列上有索引。
然而,让我挑战你的设计。看起来你正试图解决传统索引的全文索引问题。我建议在最终确定设计之前查看SQL Server中的全文索引引擎。
答案 2 :(得分:0)
我会使用动态sql并消除任何null参数的搜索条件,并消除所有的慢速或子句。它们可能会导致优化跳过有用的索引。