创建索引以优化存储过程的执行

时间:2010-07-13 11:34:40

标签: sql sql-server-2005 indexing

我的一个查询的WHERE子句如下所示:

and tbl0.Type = 'Alert' 
AND (tbl0.AccessRights like '%'+TblCUG0.userGroup+'%' 
     or tbl0.AccessRights like 'All' )
AND (tbl0.ExpiryDate > CONVERT(varchar(8), GETDATE(), 1)  
     or tbl0.ExpiryDate is null)
order by tbl0.Priority,tbl0.PublishedDate desc, tbl0.Title asc

我想知道哪些列可以创建索引以及哪种类型的索引最适合。另外我听说索引在开始时不能使用Like和Wild卡。那么优化查询的方法应该是什么呢。

2 个答案:

答案 0 :(得分:3)

1    and tbl0.Type = 'Alert' 
2    AND (tbl0.AccessRights like '%'+TblCUG0.userGroup+'%' 
3         or tbl0.AccessRights like 'All' )
4    AND (tbl0.ExpiryDate > CONVERT(varchar(8), GETDATE(), 1)  
5         or tbl0.ExpiryDate is null)

最有可能的是,您将无法使用具有WHERE子句的索引。

第1行,您可以在tbl0.Type上创建索引,但如果您有很多行且实际值很少,SQL Server将只跳过索引和表扫描。此外,与索引问题无关,像这样的列,代码/标志值更好作为固定宽度值char(1),tiny int等,其中“A”= alert或1 = alert。我将列命名为XyzType,其中Xyz是类型描述的内容(DoctorType,CarType等)。我将创建一个新的表XyzTye,在tb10中将FK返回到此列。这个新表有两列XyzType PK和XyzDescription,你可以扩展名称。

第2行,您是否将多个值合并到tbl0.AccessRights?并尝试使用LIKE来查找其中的值?如果是这样,将其拆分为另一个表,然后你可以删除它,并可能在那里添加一个索引。

第3行OR会终止索引使用情况。想象一下,通过电话簿查看所有“史密斯”或以“G”开头的名称,您不能只使用索引。您可以尝试将查询拆分为OR周围的UNIONUNION ALL,以便可以使用索引(一部分查找“Smith”,另一部分查找“G”)。您没有提供足够的查询来确定您的情况是否可行。您需要使用包含此UNION的派生表,以便将其加入查询的其余部分。

第4行tbl0.ExpiryDate可能会从索引中受益,但or会终止其使用,请参阅第3行注释。

第5行,您可以尝试上面讨论的OR联合技巧,或者只是不使用NULL,输入默认值为'01 / 01/3000'所以你不需要OR

答案 1 :(得分:2)

SQL Server的数据库调优顾问可以建议哪些索引将优化您的查询,包括覆盖将优化您未在查询中包含的所选列的索引。仅仅因为您添加索引并不意味着查询优化器将使用它。某些索引的使用成本可能高于其他索引,因此优化程序将使用基础表的统计信息选择bext索引。 无法使用,您可以使用将所有排序和条件列添加到索引中,但如果例如,有太少的不同优先级值使其值得存储,那将毫无用处。

你对LIKE和通配符是正确的。索引是一个btree,这意味着它可以加快对特定值或范围查询的快速搜索。开头的通配符表示查询必须触摸所有记录以检查它们是否与模式匹配。最后的通配符意味着查询只需要触摸以子字符串开头直到通配符的项目,部分将其转换为可以从索引中受益的范围查询。