我是关系数据库的新手,需要帮助建立一个基本的工作环境来查询大型(预先存在的)数据库。我已通过PGAdmin连接到我们的远程服务器,但所有基本查询都非常慢。
查询
SELECT to_char(created, 'YYYY-MM-DD'), user_id
FROM transactions
WHERE type = 'purchase'
AND created > NOW() AT TIME ZONE 'US/Mountain' - INTERVAL '1 month'
ORDER BY created;
EXPLAIN(BUFFERS, ANALYZE)
输出:
Index Scan using payments_transaction_created_42e34d6ca1e04ffe_uniq
on payments_transaction (cost=0.44..339376.18 rows=481811 width=24) (actual time=2.643..49422.733 rows=511058 loops=1)
Index Cond: (created > (timezone('US/Mountain'::text, now()) - '1 mon'::interval))
Filter: ((type)::text = 'purchase'::text)
Rows Removed by Filter: 955691
Buffers: shared hit=405597 read=295625 written=764
Planning time: 0.111 ms
Execution time: 49569.324 ms
在我有限的知识中,执行时间对我来说似乎太长了。
我应该采取哪些措施来创造最有效的环境?创建数据库的本地副本是否意味着更快的查询?还有其他因素会导致效率低下吗?
请记住,我是数据库的新手,所以没有简单的答案。
答案 0 :(得分:1)
您的查询似乎在transactions(created)
上使用了索引。你返回大约0.5M的行,同时丢弃2倍。
根据type
列中值的分布情况,您可以在文本和时间戳列上添加索引,从中受益:
CREATE INDEX ON transactions(type, created);
添加索引时的经验法则是首先为相等运算符编制索引,然后为日期编制索引。它实际上可能会大大加快您的查询速度 - 尽管我之前已经提到过,这取决于价值分布。
请记住在使用以下方法创建索引后更新表统计信息:
ANALYZE transactions;
测试数据库的本地副本确实意味着更快的处理,因为您不是通过网络发送包。相反,所有内容都在本地处理,但这不应该与您的查询有太大关系,最好始终尽可能多地在生产环境中测试。