0

我使用 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 秒,这当然超出了我们的预期。

有人能帮我吗?谢谢。

编辑:我删除了“tb01.P_USER 的 PARTITION”,它的查询速度翻了一番。现在执行计划列表如下: 在此处输入图像描述

排序占用了 98% 的查询时间,我该怎么办?如果必须,我应该删除过度功能并使用另一种更有效的方法吗?

4

2 回答 2

0

我有一系列关于 SQL 性能的完整博客文章。检查第 3 部分和第 4 部分以获得一些见解:http ://www.karafilis.net/sql-indexing-part3/

于 2013-09-25T11:18:35.303 回答
0

由于我不懂中文,我真的无法解释你的执行计划,但我怀疑当你最终从一百万条记录中选出 20 条时,排序中的大部分努力都被丢弃了。我假设您这样做是为了支持 Web 应用程序或智能客户端的分页。

1)这是您可以每天计算一次并简单存储结果的东西吗?

2) 使用现代 ansi 连接重写查询,并将尽可能多的“where”参数迁移到连接的 ON 子句中。我知道这在理论上应该无关紧要,但是我经常看到查询优化器在以这种方式编写时会做得更好。

3) 在您的情况下,从一百万行中选择 20 行本质上是任意的,因为您的 select 语句中没有 order by 子句。SQL server 不保证没有order by子句的排序顺序是一致的,实际上每次选择它都会以相同的顺序获取这些数据,直到表统计信息发生变化,以便查询优化器更改执行计划或决定重新散列哈希索引。这些事情中的任何一个基本上都可以在任意时间发生。

4) 限制查询中选择的百万行(不计算 rowif)的唯一因素是 tb12.CodeId = '410621'。如果这是你能做的最好的,好的。但是您确定您没有忽略某些事情,甚至可能您知道的不仅仅是查询优化器吗?

于 2013-09-26T15:07:38.617 回答