我试图优化需要花费太多时间的查询。这就是我所拥有的
查询就是这个
SELECT
value1,
value2,
value3,
value4,
value5,
hstore(
ARRAY['field9', 'field10', 'field11', 'field12', 'field13', 'field14'],
ARRAY[field9, field10, field11, field12, field13, field14) as metadata,
value7,
(select array((select row(f1, f2) from table2 p where p.f3 = field7))) as values_array
FROM table1
解释分析告诉我这个
QUERY PLAN
-------------------------------------------------------------------------------------------
Index Scan using table1_pkey on table1 (cost=67846.38..395773.45 rows=8419127 width=88) (actual time=7122.704..22670.680 rows=8419127 loops=1)
InitPlan 2 (returns $1)
-> Result (cost=67846.29..67846.29 rows=1 width=0) (actual time=7009.063..7009.065 rows=1 loops=1)
InitPlan 1 (returns $0)
-> Seq Scan on table2 p (cost=0.00..67846.29 rows=12689 width=20) (actual time=14.971..5069.840 rows=2537787 loops=1)
Filter: (f3 = field7)
因此,顺序扫描table2 (在查询中获取values_array),而不是索引扫描。可能是因为SELECT返回表中所有行的大约5-10%? (我听说在这种情况下,顺序扫描比索引扫描更快,因为每行需要的I / O操作量。)
无论如何,该查询中有什么明显的错误吗?服务器只是因为超时而终止
如果我通过添加 LIMIT 1000 OFFSET 0 来限制行返回量,则需要 3分钟,但覆盖整个表格(请记住:850万条记录)通过移动OFFSET,我需要大约8000次迭代。每个3分钟意味着超过15天......这是不可接受的。此外,大的OFFSETS也意味着表现不佳。
任何见解?在PostgreSQL列表中,他们建议我用JOIN替换内部查询,并使用复合类型而不是数组。我正在努力,但我有点坚持这个,欢迎任何评论。
非常感谢!
答案 0 :(得分:0)
通过表前缀所有列解决。查询现在看起来像这样
SELECT
a.value1,
a.value2,
a.value3,
a.value4,
a.value5,
hstore(
ARRAY['field9', 'field10', 'field11', 'field12', 'field13', 'field14'],
ARRAY[a.field9, a.field10, a.field11, a.field12, a.field13, a.field14) as metadata,
a.value7,
(select array((select row(p.f1, p.f2) from table2 p where p.f3 = a.field7))) as values_array
FROM table1 a
问题是table2.f3和table1.field7真的有相同的名字。有关this post of PostgreSQL general list
的更多信息