sql - dense_rank 在 SQL 服务器上填充 tempdb?

标签 sql sql-server sql-server-2008

我这里有这个查询,它使用 dense_rank 对组进行编号,以便仅选择第一组。它正在工作,但它的速度很慢并且 tempdb(SQL 服务器)变得太大以至于磁盘被填满。 dense_rank这么重的操作正常吗?在不借助编码的情况下,还应该如何完成这项工作?

select
a,b,c,d
from
    (select a,b,c,d,
    dense_rank() over (order by s.[time] desc) as gn
    from [Order] o
     JOIN Scan s ON s.OrderId = o.OrderId
     JOIN PriceDetail p ON p.ScanId = s.ScanId) as p
where p.OrderNumber = @OrderNumber
and p.Number = @Number
and p.Time > getdate() - 20
and p.gn = 1
group by a,b,c,d,p.gn

最佳答案

任何必须对大型数据集进行排序的操作都可能会填充 tempdb。 dense_rank 也不异常(exception),就像 rank、row_number、ntile 等。

您要求对自数据库启动以来每个扫描条目的似乎是全局的、完整的排序进行排序。您表达查询的方式必须在排序之前进行连接,因此排序将既大又宽。毕竟说完了,消耗了大量的 IO、CPU 和 tempdb 空间,您将结果限制为仅指定顺序和某些条件的一个小子集(其中提到投影中不存在的列,因此它们必须是一些制作的上面的例子不是真正的代码)。

  • 您在 WHERE gn=1 上有一个过滤器,后跟 GROUP BY gn。这是不必要的,gn 在谓词中已经是唯一的,因此它不能对分组依据做出贡献。
  • 您计算每个订单扫描的 dense_rank,然后按 p.OrderNumber = @OrderNumber AND p.gn = 1 进行过滤。这更没有意义。只有当@OrderNumber 恰好包含对所有订单排名为 1 的扫描时,此查询才会返回结果!它不可能是正确的。

您的查询没有意义。缓慢的事实只是一个好处。发布您的实际需求。

如果您想了解性能调查,请阅读 How to analyse SQL Server performance .

附言。通常,计算排名和选择 =1 总是可以表示为 TOP(1) 相关子查询,通常有更好的结果。显然,索引有帮助。

PPS。在没有任何聚合函数的情况下使用 group by 是另一种严重的代码味道。

关于sql - dense_rank 在 SQL 服务器上填充 tempdb?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23989563/

相关文章:

MySQL 数据库连接查询

sql - 如何按键生成日期范围的行

sql - 如何在 SQL Server 中查找列是否包含 '%'

sql - 为什么这个索引不能提高查询性能

sql - 存储过程重构

sql-server - 忽略 SQL Server 中全文搜索 (FREETEXTTABLE) 搜索列中的破折号 (-)

SQL 选择一列中的多行

sql-server - 如何改进大表的读取操作?

sql-server - SQL Server,误导性的 XLOCK 和优化

java - 如何在 JOOQ 中将 Record 转换为 Table Record?