Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/84.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
有没有办法优化SQL select中的子查询数组?_Sql_Postgresql_Query Optimization - Fatal编程技术网

有没有办法优化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? | {}