【问题标题】:Ascending sort order Index versus descending sort order index when performing OrderBy执行 OrderBy 时升序排序索引与降序排序索引
【发布时间】:2013-12-07 00:49:30
【问题描述】:

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

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 列上的 sql server 上的唯一索引中受益吗?或者我应该在 sql server 上定义两个唯一索引,一个具有升序排序,而另一个索引具有降序排序? 谢谢

编辑

以下查询:-

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

【问题讨论】:

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


    【解决方案1】:

    回答你的问题:

    所以我的问题是两个 OrderByDescending(a => a.Tag)。 & OrderBy(a => a.Tag),可以受益于 Tag 列上的 sql server ?

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

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

    使其正常工作可能很棘手,但值得付出努力,特别是如果您只获取前几行(如您的示例中)。

    如果不能马上解决,请看这个:

    在寻求性能建议时,通常最好显示实际的 SQL 查询,而不是 .NET 源代码。然后我可以告诉你要准确创建哪个索引。目前我不确定isDeletedisCompleted——这些表列或表达式是对其他列求值吗?

    编辑(添加 SQL 查询之后)

    有两种方法可以让您的查询作为indexed top-n 查询:

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

    第一个选项是对 where 子句中的列的常规索引,然后是 order by 子句中的列。但是,当您查询使用此过滤器IsDeleted &lt;&gt; cast(1 as bit) 时,它不能以保留顺序的方式使用索引。但是,如果您对查询进行重新措辞,使其看起来像这样IsDeleted = cast(0 as bit),那么它就可以工作。请看小提琴,我已经准备好了一切。是的,SQL Server 可以很聪明地知道这一点,但似乎不是。

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

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

    如果将 DESC 更改为 ASC,这两种方式仍然有效。

    重要的部分是执行计划没有显示排序操作。您也可以在 SQL Fiddle 中验证这一点(点击“查看执行计划”)。

    【讨论】:

    • IsDeleted & isCompleted 是两位列
    • 我已经使用 sql server profiler 指示的 sql 查询编辑了我的原始问题。
    • @johnG 在上面添加了建议。
    猜你喜欢
    • 2010-10-27
    • 1970-01-01
    • 2014-10-24
    • 1970-01-01
    • 2016-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-10
    相关资源
    最近更新 更多