sql - 优化排名查询

标签 sql sql-server

我正在使用此查询从 Sql Server 数据库中获取用户的排名:

select user_rank
from (select t.user_id, rank() over (order by score desc) as user_rank
  from user_stats t
 ) t
where t.user_id='some_user_id';

该表包含大约 22,000 行,查询需要 3.5 秒,这太慢了。

这个表有几个索引,这些是相关的:

user_id - Unique, NONCLUSTERED INDEX

score - Non-unique, NONCLUSTERED INDEX

如果我更改查询并使用 id(这是我的主键)而不是 user_id,那么查询执行得很快:

select user_rank
from (select t.id, rank() over (order by score desc) as user_rank
  from user_stats t
 ) t
where t.id='some_id';

检查执行计划后,我发现聚簇索引扫描成本为 92%,但我真的不明白为什么在这种情况下需要它。

可以做些什么来优化这个查询?

查询的统计信息:

SQL Server parse and compile time: CPU time = 0 ms, elapsed time = 0 ms.

SQL Server Execution Times: CPU time = 0 ms, elapsed time = 0 ms. SQL Server parse and compile time: CPU time = 0 ms, elapsed time = 0 ms.

SQL Server Execution Times: CPU time = 0 ms, elapsed time = 0 ms. SQL Server parse and compile time: CPU time = 0 ms, elapsed time = 0 ms.

SQL Server Execution Times: CPU time = 0 ms, elapsed time = 0 ms. SQL Server parse and compile time: CPU time = 0 ms, elapsed time = 0 ms.

(1 row(s) affected) Table 'users_stats'. Scan count 1, logical reads 22529, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row(s) affected)

SQL Server Execution Times: CPU time = 78 ms, elapsed time = 3576 ms. SQL Server parse and compile time: CPU time = 0 ms, elapsed time = 0 ms.

SQL Server Execution Times: CPU time = 0 ms, elapsed time = 0 ms.

最佳答案

我怀疑你性能下降的主要原因是你的索引没有覆盖。通过进行索引覆盖,您可能会看到性能的显着提高。 Here是一篇讨论覆盖索引的好文章。

简而言之,索引只是提供指向行的指针。为了获得对结果集进行排名所需的“score”列的数据,引擎必须扫描聚簇索引以查找数据。如果将值包含在索引中,引擎将能够执行操作而无需聚集索引扫描。

索引应该改写如下:

CREATE UNIQUE NONCLUSTERED INDEX UQ_USER_STATS_USER_ID ON user_stats (user_id) INCLUDE (score);

关于sql - 优化排名查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28699142/

相关文章:

java - 编程决定 java 或 .Net,db 或无 db

sql - 使用 MS SQL Server 2005,如何将详细记录合并到单个逗号分隔列表中

sql - 存储过程中的可选参数 - CASE 与 OR

sql - 将字符串转换为日期和时间

mysql - 如何编写 SQL 语句,例如下面的例子

sql - 在 Ruby on Rails 中连接 SQL 服务器

java - 将 1GB 文件的内容流式传输到单列下的 sqlite 表

sql - 优化右连接

sql-server - SQL Server 选择所有行内存性能

sql - 插入和删除的伪表存储在哪里?