GVKun编程网logo

为什么尽管索引了有序列,但我的SQL Server ORDER BY还是很慢?(为什么sql使用了索引还是慢查询)

7

在本文中,我们将为您详细介绍为什么尽管索引了有序列,但我的SQLServerORDERBY还是很慢?的相关知识,并且为您解答关于为什么sql使用了索引还是慢查询的疑问,此外,我们还会提供一些关于MYS

在本文中,我们将为您详细介绍为什么尽管索引了有序列,但我的SQL Server ORDER BY还是很慢?的相关知识,并且为您解答关于为什么sql使用了索引还是慢查询的疑问,此外,我们还会提供一些关于MYSQL - 实现 sqlserver- row_number () over (partition by order by) 分组排序功能、ORDER BY在Sql Server 2008视图中、Sql Server2005 的快速分页 ROW_NUMBER() OVER (ORDER BY Report、sql-server – SQL Server Developer Edition与SQL Server Standard的有用信息。

本文目录一览:

为什么尽管索引了有序列,但我的SQL Server ORDER BY还是很慢?(为什么sql使用了索引还是慢查询)

为什么尽管索引了有序列,但我的SQL Server ORDER BY还是很慢?(为什么sql使用了索引还是慢查询)

我有一个SQL查询(由LINQ to Entities生成),大致类似于以下内容:

SELECT * FROM [mydb].[dbo].[employees]JOIN [mydb].[dbo].[industry]  ON jobs.industryId = industry.idJOIN [mydb].[dbo].[state]  ON jobs.stateId = state.idJOIN [mydb].[dbo].[positionType]  ON jobs.positionTypeId = positionType.idJOIN [mydb].[dbo].[payPer]  ON jobs.salaryPerId = payPer.idJOIN [mydb].[dbo].[country]  ON jobs.countryId = country.idWHERE countryName = ''US''ORDER BY startDatetime

该查询返回大约1200行,我认为这不是一个很大的行。不幸的是,这也需要约16秒。如果没有ORDER BY,查询将花费不到1秒的时间。

我已经使用SQL Server Management Studio在startDatetime列上添加了索引,还在“
cityId,industryId,startDatetime,positionTypeId,payPerId,stateId”(即我们在“作业”中使用的所有列)上创建了聚集索引。联接和在列上我们使用ORDER
BY on)。我已经在JOIN中使用的每个列上都有单独的索引。不幸的是,这并没有使查询更快。

我运行了一个展示计划,并得到:

   |--Nested Loops(Inner Join, OUTER REFERENCES:([mydb].[dbo].[jobs].[cityId]))       |--Nested Loops(Inner Join, OUTER REFERENCES:([mydb].[dbo].[jobs].[stateId]))       |    |--Nested Loops(Inner Join, OUTER REFERENCES:([mydb].[dbo].[jobs].[industryId]))       |    |    |--Nested Loops(Inner Join, OUTER REFERENCES:([mydb].[dbo].[jobs].[positionTypeId]))       |    |    |    |--Nested Loops(Inner Join, OUTER REFERENCES:([mydb].[dbo].[jobs].[salaryPerId]))       |    |    |    |    |--Sort(ORDER BY:([mydb].[dbo].[jobs].[issueDatetime] ASC))       |    |    |    |    |    |--Hash Match(Inner Join, HASH:([mydb].[dbo].[currency].[id])=([mydb].[dbo].[jobs].[salaryCurrencyId]))       |    |    |    |    |         |--Index Scan(OBJECT:([mydb].[dbo].[currency].[IX_currency]))       |    |    |    |    |         |--Nested Loops(Inner Join, WHERE:([mydb].[dbo].[jobs].[countryId]=[mydb].[dbo].[country].[id]))       |    |    |    |    |              |--Index Seek(OBJECT:([mydb].[dbo].[country].[IX_country]), SEEK:([mydb].[dbo].[country].[countryName]=''US'') ORDERED FORWARD)       |    |    |    |    |              |--Clustered Index Scan(OBJECT:([mydb].[dbo].[jobs].[PK_jobs]))       |    |    |    |    |--Clustered Index Seek(OBJECT:([mydb].[dbo].[payPer].[PK_payPer]), SEEK:([mydb].[dbo].[payPer].[id]=[mydb].[dbo].[jobs].[salaryPerId]) ORDERED FORWARD)       |    |    |    |--Clustered Index Seek(OBJECT:([mydb].[dbo].[positionType].[PK_positionType]), SEEK:([mydb].[dbo].[positionType].[id]=[mydb].[dbo].[jobs].[positionTypeId]) ORDERED FORWARD)       |    |    |--Clustered Index Seek(OBJECT:([mydb].[dbo].[industry].[PK_industry]), SEEK:([mydb].[dbo].[industry].[id]=[mydb].[dbo].[jobs].[industryId]) ORDERED FORWARD)       |    |--Clustered Index Seek(OBJECT:([mydb].[dbo].[state].[PK_state]), SEEK:([mydb].[dbo].[state].[id]=[mydb].[dbo].[jobs].[stateId]) ORDERED FORWARD)       |--Clustered Index Seek(OBJECT:([mydb].[dbo].[city].[PK_city]), SEEK:([mydb].[dbo].[city].[id]=[mydb].[dbo].[jobs].[cityId]) ORDERED FORWARD)

重要的一行似乎是“ | –Sort(ORDER BY:([mydb]。[dbo]。[jobs]。[issueDatetime] ASC)))”
―在该列上未提及任何索引。

为什么我的ORDER BY使查询变慢得多,如何加快查询速度?

答案1

小编典典

如果您的查询之前不包含订单,则它将以找到的顺序返回数据。不能保证再次运行查询时,数据甚至会以相同的顺序返回。

当您包含order by子句时,dabatase必须按正确的顺序构建行列表,然后按该顺序返回数据。这可能需要大量额外的处理,从而转化为额外的时间。

对大量列进行排序可能需要更长的时间,您的查询可能正在返回这些列。在某些时候,您将耗尽缓冲区空间,并且数据库将必须开始交换,并且性能将下降。

尝试返回较少的列(指定所需的列而不是Select *),并查看查询是否运行得更快。

MYSQL - 实现 sqlserver- row_number () over (partition by order by) 分组排序功能

MYSQL - 实现 sqlserver- row_number () over (partition by order by) 分组排序功能

sqlserver:

with Result as
    (
        select SUM(F_DayValue) AS F_Value,F_ZZ_ttBuildID,F_EnergyItemCode 
        from T_EC_EnergyItemDayResult        
        where F_EnergyItemCode like ''%000''
        and F_StartDay>=@ldStartDate and F_StartDay<=@ldEndDate
        and F_ZZ_ttBuildID IN (select F_BuildID from T_BD_BuildBaseInfo)
        group by F_ZZ_ttBuildID,F_EnergyItemCode
    )
    select a.F_Value,a.F_ZZ_ttBuildID,b.F_BuildName,a.F_EnergyItemCode,
    ROW_NUMBER() over(partition by a.F_EnergyItemCode order by a.F_Value desc) as nsort 
    from Result a
    left join T_BD_BuildBaseInfo b on a.F_ZZ_ttBuildID=b.F_BuildID

 

mysql:

 
CREATE TEMPORARY TABLE IF NOT EXISTS Result
    (
     select SUM(F_DayValue) AS F_Value,F_ZZ_ttBuildID,F_EnergyItemCode 
        from T_EC_EnergyItemDayResult        
        where F_EnergyItemCode like ''%000''
        and F_StartDay>=V_ldStartDate and F_StartDay<=V_ldEndDate
        and F_ZZ_ttBuildID IN (select F_BuildID from T_BD_BuildBaseInfo)
        group by F_ZZ_ttBuildID,F_EnergyItemCode
    );
CREATE TEMPORARY TABLE IF NOT EXISTS TMP01
    (
     select a.F_Value,a.F_ZZ_ttBuildID,b.F_BuildName,a.F_EnergyItemCode
    from Result a 
    left join T_BD_BuildBaseInfo b on a.F_ZZ_ttBuildID=b.F_BuildID
    );
 select F_Value,F_ZZ_ttBuildID,F_BuildName,F_EnergyItemCode,nsort from (
 select heyf_tmp.F_Value,heyf_tmp.F_ZZ_ttBuildID,heyf_tmp.F_BuildName,heyf_tmp.F_EnergyItemCode,@rownum
    :=@rownum+1 ,
 if(@pdept=heyf_tmp.F_EnergyItemCode,@rank:=@rank+1,@rank:=1) as nsort,
 @pdept:=heyf_tmp.F_EnergyItemCode
 from (
 select F_Value,F_ZZ_ttBuildID,F_BuildName,F_EnergyItemCode from TMP01 order by F_EnergyItemCode ASC 
    ,F_Value desc
) heyf_tmp ,(select @rownum :=0 , @pdept := null ,@rank:=0) a) T;

 

 

 

ORDER BY在Sql Server 2008视图中

ORDER BY在Sql Server 2008视图中

我们在我们的数据库中有一个视图,其中有一个ORDER BY.
现在,我意识到一般不要命令,因为不同的人可能会使用它的不同的东西,并希望有不同的订单.然而,该视图用于要求一定顺序的非常特殊的用例. (这是足球联赛的球队排名.)

数据库是Windows Server 2003 R2框上的sql Server 2008 Express,v.10.0.1763.0.

视图的定义如下:

CREATE VIEW season.CurrentStandingsOrdered
AS
    SELECT TOP 100 PERCENT *,season.GetRanking(TEAMID) RANKING   
    FROM season.CurrentStandings 
    ORDER BY 
        GENDER,TEAMYEAR,CODE,POINTS DESC,FORFEITS,GOALS_AGAINST,GOALS_FOR DESC,DIFFERENTIAL,RANKING

它返回:

GENDER,TEAMID,CLUB,NAME,WINS,LOSSES,TIES,GOALS_FOR,POINTS,RANKING

现在,当我针对视图运行SELECT时,它会按照GENDER,TEAMID命令结果.注意,按照order by子句指定,它是由TEAMID而不是POINTS排序的.

但是,如果我复制sql语句并完全按照新查询窗口中的方式运行,则它将按照ORDER BY子句的指定正确地进行命令.

解决方法

ORDER BY子句视图返回的行的顺序是绝对不会保证的.如果您需要特定的行顺序,则必须指定从视图中选择的位置.

请参阅this Book On-Line条目顶部的注释.

Sql Server2005 的快速分页 ROW_NUMBER() OVER (ORDER BY Report

Sql Server2005 的快速分页 ROW_NUMBER() OVER (ORDER BY Report

前面一篇随笔,我提到了Sql Server 2000的自定义分页,但是在sql server 2000中,要实现显示某一页,就返回那一页数据的效果的方法实在不尽人意.网上很多通用的分页存储过程,但看着就头大.如果使用我前面提到的使用in,not in,top来进行返回特定页,特殊的限制又会

   前面一篇随笔,我提到了Sql Server 2000的自定义分页,但是在sql server 2000中,要实现显示某一页,就返回那一页数据的效果的方法实在不尽人意.网上很多通用的分页存储过程,但看着就头大.如果使用我前面提到的使用in,not in,top来进行返回特定页,特殊的限制又会比较多(比如ID要递增).现在Sql Server 2005中提供了一个函数ROW_NUMBER(),可以使自定义分页变得简单许多.
    我们先来看看ROW_NUMBER()是干什么的.执行下面这段SQL语句:
    SELECT [ReportID],[UserName], [ReportID],
    [TimeStart], [TimeEnd],ROW_NUMBER() OVER (ORDER BY ReportID) AS RowNo
    FROM [ExecutionLog]
    执行结果如下图所示:
   
     很简单,ROW_NUMBER() 就是生成一个顺序的行号,而他生成顺序的标准,就是后面紧跟的OVER(ORDER BY ReportID).现在,你看到了自定义分页的影子了吗?:)下面,我们看看怎么具体应用这个RowNo进行分页.

    现在,假设我每一页的数据是10条,我们就可以使用如下所示的SQL语句返回指定页的数据:
    @"
      SELECT TOP 10 *
      FROM
      (
       SELECT top 10 [InstanceName], [UserName], [ReportID],
       [TimeStart], [TimeEnd],ROW_NUMBER() OVER (ORDER BY ReportID) AS RowNo
       FROM [ExecutionLog]
      ) AS A
      WHERE RowNo > " + pageIndex*10
    pageIndex就是我们需要数据的页数.很简单,不是吗?并且,这种方式几乎没有什么限制,因为他相当于对于任何检索,都生成了一个新的排序列.我们就可以使用该列进行自定义分页.

----2005.11.26 11:43 星期六 

sql-server – SQL Server Developer Edition与SQL Server Standard

sql-server – SQL Server Developer Edition与SQL Server Standard

我不确定我理解这一点,但我会把我的假设抛在那里:

sql Server 2008 Standard&企业版本用于在服务器上运行完整的数据库服务(不仅仅是为了比较),

和sql Server Developer Edition是什么,一个围绕sql Server开发程序的IDE ???

不确定我明白了吗?

解决方法

Developer Edition只是企业版,没有在生产环境中使用的许可.此外,它不需要安装在服务器操作系统上(即,您可以将它放在Win7,Vista,XP上).

我们今天的关于为什么尽管索引了有序列,但我的SQL Server ORDER BY还是很慢?为什么sql使用了索引还是慢查询的分享已经告一段落,感谢您的关注,如果您想了解更多关于MYSQL - 实现 sqlserver- row_number () over (partition by order by) 分组排序功能、ORDER BY在Sql Server 2008视图中、Sql Server2005 的快速分页 ROW_NUMBER() OVER (ORDER BY Report、sql-server – SQL Server Developer Edition与SQL Server Standard的相关信息,请在本站查询。

本文标签: