Sql 为什么这个pg查询这么慢?我怎样才能使它更快?
以下是查询:Sql 为什么这个pg查询这么慢?我怎样才能使它更快?,sql,postgresql,indexing,query-performance,Sql,Postgresql,Indexing,Query Performance,以下是查询: (SELECT * FROM url WHERE domain = 'youtube.com' AND timestamp > NOW() - INTERVAL '24 hours' ORDER BY likes DESC LIMIT 10) UNION (SELECT * FROM url WHERE domain = 'twitter.com' AND timestamp > NOW() - INTERVAL '24 hours' ORD
(SELECT *
FROM url
WHERE domain = 'youtube.com'
AND timestamp > NOW() - INTERVAL '24 hours'
ORDER BY likes DESC LIMIT 10)
UNION
(SELECT *
FROM url
WHERE domain = 'twitter.com'
AND timestamp > NOW() - INTERVAL '24 hours'
ORDER BY likes DESC LIMIT 10)
UNION
(SELECT *
FROM url
WHERE domain = 'reddit.com'
AND timestamp > NOW() - INTERVAL '24 hours'
ORDER BY likes DESC LIMIT 10)
ORDER BY timestamp DESC
这是解释分析
如果你有兴趣自己运行它
我看到有一百万条推特行被过滤,但我不知道如何避免。我有一个时间戳索引,我希望它能被用来代替按喜好排序和扫描整个东西。这是否意味着我需要一个综合指数?有没有办法让计划者使用两个索引而不是另一个索引
p、 我想我搞错了,主键是url。它会使索引不必要地变大。PostgreSQL尝试在likes上使用索引,以避免排序以获得前10个结果,但它必须放弃许多行才能达到目的 也许那个执行计划是最好的,也许不是 遵循以下步骤: 在电子表格上运行分析,看看这是否解决了问题 若并没有,那个么在域上创建一个索引,按那个顺序添加时间戳!看看这是否能改善情况 如果这还不够的话 如果可以的话,把索引放在likes上 或 将按喜欢排序更改为按喜欢排序+0。
如果所有这些都不能使它变得更好,那么您最初的查询计划是最好的,您所能做的就是使用更多的RAM,希望缓存中有更多的数据。我建议这样编写查询:
SELECT ufiltered.*
FROM (SELECT url.*,
ROW_NUMBER() OVER (PARTITION BY domain ORDER BY likes DESC) AS seqnum
FROM url
WHERE domain IN ('youtube.com', 'twitter.com', 'reddit.com') AND
timestamp > NOW() - INTERVAL '24 hours'
) AS ufiltered
WHERE seqnum <= 10
ORDER BY timestamp DESC
为此,我建议在urltimestamp、domain和likes上建立一个索引。UNION ALL而不是UNION可能会对其有所改进。很难判断,因为数字不稳定,但可能会有5%的变化。谢谢你提到它。@一匹没有名字的马。虽然这是一个最佳实践,但在30行上使用union和union all并不会产生很大的区别。只是尝试了按likes+0排序,这已经导致pg避免使用likes索引,并将我的时间从20秒减少到0.25秒。我会测试你的其他想法,但这已经值得一分了。非常感谢。我建议最后一个,因为这是最不优雅的解决方案。分析url似乎什么都没做。我的索引有点大,所以我对此有点害羞,但可能稍后会尝试。好吧,然后选择第三个选项。我必须编辑,因为没有定义seqnum,但是这个查询似乎比较快,没有使用views+0技巧,而且大约短了100个字符。我要了。当我用了1年后,我得到了QueryFailedError:临时文件大小超过了临时文件大小限制3193019kB。因此,我最终使用了问题的原始查询,没有强制索引。不同的时间框架需要不同的索引。
SELECT ufiltered.*
FROM (SELECT url.*,
ROW_NUMBER() OVER (PARTITION BY domain ORDER BY likes DESC) AS seqnum
FROM url
WHERE domain IN ('youtube.com', 'twitter.com', 'reddit.com') AND
timestamp > NOW() - INTERVAL '24 hours'
) AS ufiltered
WHERE seqnum <= 10
ORDER BY timestamp DESC