我有以下查询,
SELECT * FROM users,
(SELECT *
FROM mastery
WHERE champion_rank = 1
ORDER BY global_rank ASC
LIMIT 3) as ranks
WHERE users.id = ranks.user_id
掌握有22M行,用户有5M行。上面的查询需要1800毫秒才能完成。
问题是以下子查询在运行时需要2.5ms才能执行
SELECT *
FROM mastery
WHERE champion_rank = 1
ORDER BY global_rank ASC
LIMIT 3
从users表中检索单个用户需要2.5ms
SELECT * FROM users WHERE id = 4234523
理论上如果我只是修改了我的代码来执行第一个子查询,然后对于返回的每一行运行一个额外的查询,整个过程将花费2.5 +(3 * 2.5)= 10 ms来运行。
当然postgres做了一些奇怪的事情?
可以找到数据库的结构和索引here
答案 0 :(得分:0)
您的查询运行缓慢,因为它必须为用户的5M行中的每一行运行已排序的子查询。
你可以更好地进行连接单次传递,并使用rank()窗口函数来过滤你想要的3个顶级传递:
SELECT users.*, (ranks.mastery).*
FROM (
SELECT mastery, rank() OVER (ORDER BY global_rank)
FROM mastery
WHERE champion_rank = 1
) as ranks
JOIN users ON (users.id = ranks.user_id)
WHERE ranks.rank <= 3;
答案 1 :(得分:0)
确定问题,我加入的两个字段的数据类型不同。 Mastery的用户ID是数据类型numeric,Users id是数据类型integer,它必须将每一行都转换为新类型。
因此查询时间长。