有没有办法优化SQL select中的子查询数组?
我现在有两张桌子有没有办法优化SQL select中的子查询数组?,sql,postgresql,query-optimization,Sql,Postgresql,Query Optimization,我现在有两张桌子 question -------- id title, character varying answer -------- id question_id votes, integer 我使用以下查询返回问题列表及其相应的投票数组: SELECT question.id, question.title, ARRAY(SELECT votes FROM answer WHERE answer.question_id = q
question
--------
id
title, character varying
answer
--------
id
question_id
votes, integer
我使用以下查询返回问题列表及其相应的投票数组:
SELECT question.id,
question.title,
ARRAY(SELECT votes
FROM answer
WHERE answer.question_id = question.id)
FROM question
ORDER BY question.id
输出如下所示:
id | title | ?column?
----+----------+-----------------------------------------------------
100 | How to | {5,2,7}
101 | Where is | {0}
102 | What is | {1}
上面的查询可能需要将近50秒的时间来处理数十万个问题,其中每个问题至少可以有5个答案。有没有办法优化上述功能?您应该使用连接:
SELECT question.id, question.title, answer.votes
FROM question
JOIN answer ON answer.question_id == question.id
ORDER BY question.id
如果您希望输出列包含与问题关联的所有“投票”的串联列表,并且您在Postgres上,请检查此问题:如果您希望查询为每个问题生成一行,并将投票收集到一个数组中,则可以使用联接,包括:
我建议在
answer
表上创建索引,并使用原始查询
CREATE INDEX answer_question_id_idx ON answer(question_id);
如果没有这个索引,它将不得不对整个表进行顺序扫描,以找到具有匹配的question\u id
的行。对于每一个问题,它都必须这样做
可选地,考虑使用连接,AS。我不是这方面的专家,但我认为Postgres将使用散列连接,而不是多个顺序扫描,从而加快查询速度。如果要保留id/标题/数组格式,请使用:
然而,有一个警告。如果一个问题没有答案,你会得到一个奇怪的结果: id | title | array_agg
----+-------------------+-----------
1 | How do I do this? | {3,5}
2 | How do I do that? | {NULL}
(2 rows)
这是因为左联接
,当联接表中没有行可用时,它会创建一个NULL
值。使用内部联接
,第二行根本不会出现
这就是我建议使用原始查询的原因。它产生了预期的结果:
id | title | ?column?
----+-------------------+----------
1 | How do I do this? | {3,5}
2 | How do I do that? | {}
添加了类似于postgres特定语法的postgresql标记b/c。如果这不是正确的评估,请随意删除标签。表
答案的投票
列的类型是什么?它是数组还是单个整数值?我假设它是一个int
值。如果查询是数组,则该查询不起作用。请添加查询的解释分析。我已经有了此索引,但仍需要一段时间。在使用EXPLAIN
之后,我没有看到连接方法有很多改进。
id | title | array_agg
----+-------------------+-----------
1 | How do I do this? | {3,5}
2 | How do I do that? | {NULL}
(2 rows)
id | title | ?column?
----+-------------------+----------
1 | How do I do this? | {3,5}
2 | How do I do that? | {}