我的开发环境中有一个查询,通常需要 1.7 ms 才能在dev mySQL数据库上运行。当碰到Heroku和PostgreSQL时,同一数据集上的相同查询大约需要 1.2秒!
SELECT distinct user_id, score, quality
FROM `reports`
WHERE (datetime_utc >= '2012-01-13 14:00:00' AND
datetime_utc <= '2012-01-14 14:00:00')
ORDER BY score DESC, quality DESC LIMIT 20
我创建了一个关于得分和质量的复合索引,它有助于SQL版本,但是在PostgreSQL上运行的查询仍然非常非常慢。我的第一直觉是检查索引实际上是否在Heroku方面,但我不知道该怎么做 - 无论如何,我觉得这更多地与mySQL和PostgreSQL不相关的事实有关不做同样的事情。
任何见解或指示都会非常感激!
答案 0 :(得分:2)
尝试此修改后的查询:
SELECT user_id, score, quality
FROM reports
WHERE datetime_utc BETWEEN '2012-01-13 14:00:00' AND '2012-01-14 14:00:00'
GROUP BY user_id, score, quality
ORDER BY score DESC, quality DESC
LIMIT 20
由于最后应用了DISTINCT
,因此可能比具有许多非明显行的GROUP BY
慢。您必须使用EXPLAIN ANALYZE
进行测试。否则,结果是一样的。
使用BETWEEN
对WHERE子句进行少量简化。删除了非标准的MySQL语法。
(score, quality)
上的索引很难使用。这里的有用索引(在大多数情况下应该会有很大的不同):
CREATE INDEX reports_date_time_utc_idx ON reports (date_time_utc)
重要的部分是指数。
答案 1 :(得分:1)
性能上的差异可能是由dev和heroku之间的数据集大小引起的吗?
如果有一个分数索引,如果有很多行,质量将无济于事,因为它仍然必须根据datetime_utc进行过滤。
您可能希望考虑datetime_utc上的索引,因为它需要先在那里进行过滤。
如果你真的想要优化读取速度,你可以在datetime_utc,score,quality,user_id上有一个复合索引,这将完全消除查找行数据的需要。
但是,请注意这样做,因为您可能会在具有如此宽索引的插入上导致热点。
答案 2 :(得分:1)
由于Heroku不允许您连接到数据库,除非拥有&gt; 200 $ /月计划之一,您可以尝试检索数据库的本地副本以供本地检查。
heroku db:pull // Will give you a local copy of the db
结果将是这样的:
Receiving schema
Receiving data
8 tables, 591 records
users: 100% |================================| Time: 00:00:00
pages: 100% |================================| Time: 00:00:00
comments: 100% |================================| Time: 00:00:00
tags: 100% |================================| Time: 00:00:00
Receiving indexes
Resetting sequences