SQL Server中的索引使用情况:搜索与扫描

时间:2015-10-20 19:51:51

标签: sql-server indexing sql-server-2008-r2 database-performance

给出以下架构:

create table dbo.SomeTable 
(
    ID int primary key identity(1, 1),
    SomeColumn varchar(50)
);

create index IX_SomeColumn on dbo.SomeTable (SomeColumn);

并填充一些数据:

declare @i int = 1000;

while @i > 0 begin
    set @i = @i - 1;

    insert dbo.SomeTable (SomeColumn) 
    values (convert(varchar, @i))
end

此查询执行索引搜索:

select ID 
from dbo.SomeTable 
where SomeColumn = '431'

此查询执行索引扫描时:

select ID 
from dbo.SomeTable 
where case when SomeColumn = '431' then 1 else 0 end = 1

有没有办法让后者(或类似的东西)执行索引搜索?

我在问,因为我希望能够将case when放入视图的选择列表并在where子句中使用它,但它永远不会像原始一样好用如果我不能让SQL Server进行索引搜索,那么就形成了。

2 个答案:

答案 0 :(得分:6)

你可以通过使case when SomeColumn = '431' then 1 else 0 end表达式成为计算列并索引计算列来获得搜索的唯一方法。

然后,您应该发现表达式与允许搜索的计算列匹配(以维持额外索引为代价)。

(如果您遇到自动对等计划出现问题而无法匹配,则会添加冗余1=1会阻止此操作。SQL Fiddle with plan showing a seek

答案 1 :(得分:3)

如果查看两个查询的执行计划,搜索谓词就会大不相同。

当你在where子句中没有使用CASE表达式时,搜索谓词只留下列(不必对列值进行任何计算),只需对索引进行搜索以在另一个上找到值<script type="text/javascript"> jQuery('input[name="location"]').click(function(){ var data = {location : jQuery(this).val(), department : $('input[name="department"]:checked').val()}; jQuery.ajax({ url: "/new-fields.php", type:'POST', data: data, dataType: 'text', success: function(result){ jQuery('#div-custom').html(result).show(); $("#div-custom").find("script").each(function() { eval($(this).text()); }); } }); }); </script> 的一面。

enter image description here

另一方面,当你在where子句中使用CASE表达式时,事情会发生很大的变化,现在搜索谓词已经在Where表达式的两边参数化了where子句。简单来说,在 $picker = '<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css"> <script src="//code.jquery.com/jquery-1.10.2.js"></script> <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script> <script> $(function() { $( "#datepicker1" ).datepicker({ numberOfMonths: 3, showButtonPanel: true }); }); </script> <script> $(function() { $( "#datepicker2" ).datepicker({ numberOfMonths: 3, showButtonPanel: true }); }); </script> <p>Date: <input type="text" id="datepicker1"></p> <p>Date: <input type="text" id="datepicker2"></p>'; echo $picker; 实际执行之前,SQL服务器不会产生什么值,因此使用可用的索引选项会超出窗口,SQL服务器最终会进行扫描。

enter image description here

故事的道德

避免在where子句中使用CASE表达式。