执行OrderBy时升序排序顺序索引与降序排序顺序索引

时间:2013-12-07 00:49:31

标签: asp.net-mvc linq entity-framework sql-server-2008-r2 indexing

我正在开发一个asp.net mvc Web应用程序,我正在使用Sql server 2008 R2 + Entity框架。 现在在sql服务器上,我已经在任何可能排序的列上添加了唯一索引。例如,我在Tag colum上的Sql服务器上创建了一个唯一索引,并且我已经定义索引的排序顺序为Ascending。现在我在我的应用程序中有一些查询,命令标记升序,而其他查询命令标记降序,如下所示: -

LatestTechnology = tms.Technologies.Where(a=> !a.IsDeleted && a.IsCompleted).OrderByDescending(a => a.Tag).Take(pagesize).ToList(),;

TechnologyList = tms.Technologies.Where(a=> !a.IsDeleted && a.IsCompleted).OrderBy (a => a.Tag).Take(pagesize).ToList();

所以我的问题是两个OrderByDescending(a => a.Tag)。 &安培; OrderBy(a => a.Tag),可以从Tag colum上的sql server上的asending唯一索引中受益吗?或者我应该在sql server上定义两个唯一索引,一个是升序排序,而另一个索引是decedning排序顺序? 感谢

修改

以下查询: -

LatestTechnology = tms.Technologies.Where(a=> !a.IsDeleted && a.IsCompleted).OrderByDescending(a => a.Tag).Take(pagesize).ToList();

将生成sql server profiler提到的以下sql语句: -

  SELECT TOP (15) 

        [Extent1].[TechnologyID] AS [TechnologyID], 
        [Extent1].[Tag] AS [Tag], 
        [Extent1].[IsDeleted] AS [IsDeleted], 
        [Extent1].[timestamp] AS [timestamp], 
        [Extent1].[TypeID] AS [TypeID], 
        [Extent1].[StartDate] AS [StartDate], 
        [Extent1].[IT360ID] AS [IT360ID], 
        [Extent1].[IsCompleted] AS [IsCompleted]
        FROM [dbo].[Technology] AS [Extent1]
        WHERE ([Extent1].[IsDeleted] <> cast(1 as bit)) AND ([Extent1].[IsCompleted] = 1)
        ORDER BY [Extent1].[Tag] DESC

1 个答案:

答案 0 :(得分:2)

回答你的问题:

  

所以我的问题是两个OrderByDescending(a =&gt; a.Tag)。 &安培;   OrderBy(a =&gt; a.Tag),可以从上面的asending唯一索引中受益   Tag colum上的sql server?

是的,SQL Server可以在两个方向读取索引:如索引定义或完全相反的方向。

但是,从您的介绍中我怀疑您对order by索引的工作方式仍有错误的印象。如果同时具有where子句和order by子句,则必须确保具有涵盖这两个子句的单个索引!拥有where子句的索引(例如isDeletedisCompleted - 无论您的示例中是什么)和tag上的另一个索引都没有帮助。您需要拥有一个索引,该索引首先包含where子句的列,后跟order by子句的列(多列索引)。

让它正常工作可能会很棘手,但值得付出努力,特别是如果你只获取前几行(如你的例子中)。

如果它不能立即解决,请看一下:

在询问性能建议时,通常最好显示实际的SQL查询 - 而不是.NET源代码。然后我可以告诉你准确创建哪个索引。目前我不确定isDeletedisCompleted - 这些表列或表达式是否在其他列上进行评估?

编辑(添加SQL查询后)

有两种方法可以使您的查询作为索引的top-n 查询工作:

http://sqlfiddle.com/#!6/260fb/4

第一个选项是where子句中的列的常规索引,后跟order by子句中的列。但是,当您查询使用此过滤器IsDeleted <> cast(1 as bit)时,它无法以保留顺序的方式使用索引。但是,如果您重新对查询进行短语,使其显示为IsDeleted = cast(0 as bit),那么它可以正常工作。请看小提琴,我已经准备好了。是的,SQL Server可以足够聪明地知道,但似乎不是。

我不知道如何调整EF以上述方式生成查询,抱歉。

但是,还有第二个选项使用所谓的过滤索引 - 这是一个仅包含表行子集的索引。它也在SQL Fiddle中。在这里,重要的是将where子句添加到索引定义中,方法与查询中显示的方式相同。

如果将DESC更改为ASC,它仍然可以正常工作。

重要的是,执行计划不显示排序操作。您还可以在SQL Fiddle中验证这一点(单击“查看执行计划”)。