以下是一个postgres查询,似乎比我预期的要长得多。 field_instances表在form_instance_id和field_id上编制索引,form_instances表在workflow_state上编制索引。所以我认为这将是一个快速的查询,但它需要永远。任何人都可以帮我解释查询计划以及要添加哪种索引以加快速度吗?感谢。
explain analyze
select form_id,form_instance_id,answer,field_id
from form_instances,field_instances
where workflow_state = 'DRqueued'
and form_instance_id = form_instances.id
and field_id = 'Book_EstimatedDueDate';
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Hash Join (cost=8733.85..95692.90 rows=9277 width=29) (actual time=2550.000..15430.000 rows=11431 loops=1)
Hash Cond: (field_instances.form_instance_id = form_instances.id)
-> Bitmap Heap Scan on field_instances (cost=2681.11..89071.72 rows=47567 width=25) (actual time=850.000..13690.000 rows=51726 loops=1)
Recheck Cond: ((field_id)::text = 'Book_EstimatedDueDate'::text)
-> Bitmap Index Scan on index_field_instances_on_field_id (cost=0.00..2669.22 rows=47567 width=0) (actual time=830.000..830.000 rows=51729 loops=1)
Index Cond: ((field_id)::text = 'Book_EstimatedDueDate'::text)
-> Hash (cost=5911.34..5911.34 rows=11312 width=8) (actual time=1590.000..1590.000 rows=11431 loops=1)
-> Bitmap Heap Scan on form_instances (cost=511.94..5911.34 rows=11312 width=8) (actual time=720.000..1570.000 rows=11431 loops=1)
Recheck Cond: ((workflow_state)::text = 'DRqueued'::text)
-> Bitmap Index Scan on index_form_instances_on_workflow_state (cost=0.00..509.11 rows=11312 width=0) (actual time=650.000..650.000 rows=11509 loops=1)
Index Cond: ((workflow_state)::text = 'DRqueued'::text)
Total runtime: 15430.000 ms
(12 rows)
答案 0 :(得分:4)
当你说 field_instances_id和field_id 上的field_instances表被编入索引时,你的意思是该表上的form_instance_id和field_id上有单独的索引?
尝试删除form_instance_id
上的索引并在(form_instance_id, field_id)
上添加连锁索引。
索引的工作原理是为您提供快速查找,告诉您哪些行与您的索引匹配。然后它必须通过这些行来执行您想要的操作。因此,您始终希望索引尽可能具体。如果在表上放置两个索引,则有两种不同的方法可以进行查找,但查询通常只会利用其中一个。如果在表上放置连接索引,您将能够有效地查找索引中的第一个字段,前两个字段等。 (因此(a, b)
上的连锁索引可以让您快速查找a
,更快地查找a
和b
,但无法帮助您查看b
{1}})
现在它正在找出form_instances
中具有正确状态的所有可能事物。它分别计算出具有正确字段ID的所有field_instances
。然后它进行散列连接。为此,从一个结果集中创建查找哈希,并扫描另一个结果集。
根据我的建议,它应该找出所有可能感兴趣的form_instances
。然后它将转到索引,并找出匹配两者表单实例和字段ID的所有field_instances
,然后它将找到确切感兴趣的结果。由于索引更具体,因此数据库将有更少的数据行来处理您的查询。
答案 1 :(得分:1)
http://explain.depesz.com是一款出色的在线工具,可帮助您直观地识别热点。我将您的结果粘贴到工具中并进行了此分析:http://explain.depesz.com/s/VIk
然而,如果没有看到你的表格和索引,很难说清楚。
答案 2 :(得分:0)
需要知道你的表中的数据,但只需查看我推荐的sql和列名称
field_id
检查where语句中的第一个条件