【发布时间】:2023-04-09 23:02:01
【问题描述】:
我有一个包含列(id、xp、...)和大约 150 万行的用户表。
我通过以下查询(执行时间为 33 秒)获取某人在 XP 排行榜中的位置:
EXPLAIN ANALYZE WITH counts AS (
SELECT DISTINCT
id,
ROW_NUMBER () OVER (ORDER BY xp DESC)
FROM
users
) SELECT
*
FROM
counts
WHERE
id=1;
Subquery Scan on counts (cost=344492.80..395160.57 rows=7404 width=16) (actual time=30683.244..32174.117 rows=1 loops=1)
Filter: (counts.id = '1'::bigint)
Rows Removed by Filter: 1481060
-> HashAggregate (cost=344492.80..376651.79 rows=1480702 width=24) (actual time=30679.440..32034.921 rows=1481061 loops=1)
Group Key: users.id, row_number() OVER (?)"
Planned Partitions: 64 Batches: 65 Memory Usage: 4369kB Disk Usage: 125960kB
-> WindowAgg (cost=212155.06..238067.34 rows=1480702 width=24) (actual time=2983.137..20302.548 rows=1481061 loops=1)
-> Sort (cost=212155.06..215856.81 rows=1480702 width=16) (actual time=2983.082..5040.782 rows=1481061 loops=1)
Sort Key: users.xp DESC
Sort Method: external merge Disk: 37760kB
-> Seq Scan on users (cost=0.00..35094.02 rows=1480702 width=16) (actual time=25.467..880.626 rows=1481061 loops=1)
Planning Time: 2.593 ms
JIT:
Functions: 14
Options: Inlining false, Optimization false, Expressions true, Deforming true"
Timing: Generation 12.061 ms, Inlining 0.000 ms, Optimization 1.503 ms, Emission 26.086 ms, Total 39.650 ms"
Execution Time: 32325.206 ms
我的表定义:
CREATE TABLE users
(
id bigint NOT NULL
CONSTRAINT users_pkey
PRIMARY KEY,
xp bigint DEFAULT 0 NOT NULL,
...
);
CREATE INDEX user_xp_leaderboard_index
ON users (xp DESC, id ASC);
但它非常慢。尽管考虑到它对整个表进行排序并过滤它并不奇怪,但我不知道如何改进/优化这个查询。
我做了SET work_mem TO '1 GB';。有一点帮助,但不大。
任何帮助将不胜感激。提前致谢。
【问题讨论】:
-
xp上的索引? -
Filter: (counts.id = '90076279646212096'::bigint) -
我是索引新手。你能解释一下我应该如何创建索引并据此更改我的查询吗? @Amadan
-
90076279646212096是我在示例查询中使用的 ID,而不是1。我会解决的。对不起。 @wildplasser -
这实际上有助于进一步。谢谢你。 @wildplasser
标签: sql postgresql query-optimization window-functions