在本文中,我们将为您详细介绍为什么尽管索引了有序列,但我的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使用了索引还是慢查询)
- 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查询(由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) 分组排序功能
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视图中
现在,我意识到一般不要命令,因为不同的人可能会使用它的不同的东西,并希望有不同的订单.然而,该视图用于要求一定顺序的非常特殊的用例. (这是足球联赛的球队排名.)
数据库是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子句的指定正确地进行命令.
解决方法
请参阅this Book On-Line条目顶部的注释.
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 2008 Standard&企业版本用于在服务器上运行完整的数据库服务(不仅仅是为了比较),
和sql Server Developer Edition是什么,一个围绕sql Server开发程序的IDE ???
不确定我明白了吗?
解决方法
我们今天的关于为什么尽管索引了有序列,但我的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的相关信息,请在本站查询。
本文标签: