我使用SQL Server 2008,我的SQL查询如下所示:
select * from (
select row_number() over(PARTITION by tb01.P_USER order by tb04.P_data7 desc) Row
,tb01.P_USER as 'enterpriseID'
,tb01.P_ID as 'greenhouseID'
,tb01.P_NAME as 'greenhouseName'
,tb04.P_data1 as 'airTemp'
,tb04.P_data2 as 'airHi'
,tb04.P_data3 as 'soilTemp'
,tb04.P_data4 as 'soilHi'
,tb04.P_data5 as 'co'
,tb04.P_data6 as 'sun'
,tb04.P_data7 as 'pickingTime'
,tb05.P_data5 as 'params'
from TB04 tb04,TB01 tb01,TB05 tb05,TB12 tb12
where tb04.P_data8 = tb05.P_data2
and tb05.P_data1=tb01.P_ID
and tb01.P_USER = tb12.P_data1
and tb12.CodeId = '410621'
) result where Row between (3-1)*20+1 and 3*20
我想挑出20个,但是当我运行这个SQL时,花了大约8秒钟,这当然超出了我们的预期。
有人会帮助我吗?thx。
编辑: 我删除了“由tb01.P_USER分区”,其查询速度加倍。 现在exec计划列出如下:
排序需要98%的查询时间,我该怎么做?我应该删除过功能并使用其他更有效的方法吗?
答案 0 :(得分:0)
我有一系列关于SQL性能的博客文章。检查第3部分和第4部分,了解一些见解:http://www.karafilis.net/sql-indexing-part3/
答案 1 :(得分:0)
由于我不读中文,我真的无法解释你的执行计划,但我怀疑当你最终选择了100个记录中的20个记录时,大部分的努力都被丢弃了。我会假设您这样做是为了支持Web应用程序或智能客户端的分页。
1)这是你每天可以计算一次并只存储结果吗?
2)使用现代ansi连接重写查询,并将尽可能多的“where”参数迁移到连接的ON子句中。我知道它在理论上并不重要,但我经常看到查询优化器在这样写的时候做得更好。
3)在你的情况下,选择20行中的20行基本上是任意的,因为你的select语句中没有order by子句。 SQL Server不保证排序顺序在没有order by子句的情况下是一致的,实际上每次选择它时都会以相同的顺序获取这些数据,直到表统计信息发生变化,以便查询优化器更改执行计划或决定重新散列散列索引。这些事情中的任何一个基本上都可以在任意时间发生。
4)限制查询中所选百万行(不计算rowif)的唯一因素是tb12.CodeId ='410621'。如果这是你能做的最好的,那好吧。但是你确定你没有忽略某些东西,甚至可能是你比查询优化器更了解的情况吗?