如何让sql运行得更快?

时间:2013-09-25 07:13:09

标签: sql performance sql-server-2008 row-number

我使用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计划列出如下: enter image description here

排序需要98%的查询时间,我该怎么做?我应该删除过功能并使用其他更有效的方法吗?

2 个答案:

答案 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'。如果这是你能做的最好的,那好吧。但是你确定你没有忽略某些东西,甚至可能是你比查询优化器更了解的情况吗?