在sqlserver 2008数据库中,我们有一个包含10列的表。在Web应用程序中,用户界面旨在允许用户在某些或所有列上指定搜索条件。 Web应用程序调用存储过程,该存储过程动态创建仅包含where子句中指定选项的sql语句,然后使用sp_executesql执行查询。
索引这些列的最佳方法是什么?我们目前有10个索引,每个索引都有不同的列。我们应该有10个指数,还是其他一些组合?
答案 0 :(得分:2)
复合索引只能在搜索条件中指定最左侧的键时使用。如果您在(A, B, C)
上有索引,则可以使用该索引搜索值WHERE A =@a
,WHERE A=@a AND B=@b
,WHERE A=@a AND C=@c
或WHERE A=@a AND B=@b AND C=@c
。但如果未指定最左侧的密钥,则无法使用它,WHERE B=@b
或WHERE C=@c
无法使用此索引。因此,每列中的10个索引可以分别用于特定的用户标准,但是如果用户在第一列中包含标准而在所有其他情况下无用,则10列上的1个索引将仅有用。至少这是10000英尺的答案。如果你开始深入了解它还有更多细节。
要全面讨论您的问题和可能的解决方案,请参阅Dynamic Search Conditions in T-SQL。
答案 1 :(得分:2)
优化动态搜索查询的圣经是由SQL Server MVP Erland Sommarskog编写的:
http://www.sommarskog.se/dyn-search.html
对于SQL Server 2008,具体为:
http://www.sommarskog.se/dyn-search-2008.html
这里有很多要消化的信息,你最终决定的将取决于查询的形成方式。是否始终搜索某些参数?是否存在通常一起请求的某些参数组合?您是否真的可以在每个列上创建索引(请记住,即使where子句中提到了多个列,也不会全部使用[编辑] 必须索引不是“免费” - 您在维护时付费吗?
答案 2 :(得分:2)
这完全取决于数据是什么:它们的索引程度如何(例如,只有两个值的列上的索引对您没有多大帮助),它们被搜索的可能性有多大,以及它们的可能性有多大要一起搜索 。
特别是,如果要查询A列,并且在查询A列时往往只查询B列,则(A,B)上的复合索引将使查询非常快速地搜索两列的特定值,并且还免费为您提供A(但不是B)的单一索引的好处。
每列一个索引可能对您的数据有意义,但更有可能不是。考虑到数据和架构的性质,可能会有更好的权衡。
我个人不打算使用存储过程来创建动态SQL。与在webapp本身中使用的任何服务器端脚本语言相比,没有性能优势,并且您编写Web应用程序的语言几乎总是具有比SQL更灵活,可读和安全的字符串处理函数确实。在SQL中生成SQL字符串本身就是一种痛苦的练习;你几乎肯定会在某个地方遇到一些错误的错误并给自己一个SQL注入安全漏洞。
答案 3 :(得分:0)
每列一个索引。问题是你对这些查询一无所知,这是最通用的方法。
答案 4 :(得分:0)
根据我的经验,使用组合索引确实可以加快查询速度。在这种情况下,您无法拥有所有可能的组合。
我建议进行一些使用测试,以确定最常使用的组合。然后专注于组合这些列的索引。如果最常见的组合是:
C1,C2,C3 C1,C2,C5
...然后在C1和C2上组合索引。