我有一个相当简单的查询,总运行时间很大。你能告诉我如何优化它吗?
这是解释分析:http://explain.depesz.com/s/9xC5
查询:
select wpis_id from spoleczniak_oznaczone
where etykieta_id in(
select tag_id
from spoleczniak_subskrypcje
where postac_id = 376476
);
spoleczniak_oznaczone:
Column | Type | Modifiers
-------------+---------+--------------------------------------------------------------------
id | integer | not null default nextval('spoleczniak_oznaczone_id_seq'::regclass)
etykieta_id | integer | not null
wpis_id | integer | not null
Indexes:
"spoleczniak_oznaczone_pkey" PRIMARY KEY, btree (id)
"spoleczniak_oznaczone_etykieta_id" btree (etykieta_id)
"spoleczniak_oznaczone_wpis_id" btree (wpis_id)
Foreign-key constraints:
"spoleczniak_oznaczone_etykieta_id_fkey" FOREIGN KEY (etykieta_id) REFERENCES spoleczniak_etykiety(id) DEFERRABLE INITIALLY DEFERRED
"spoleczniak_oznaczone_wpis_id_fkey" FOREIGN KEY (wpis_id) REFERENCES spoleczniak_tablica(id) DEFERRABLE INITIALLY DEFERRED
spoleczniak_subskrypcje:
Column | Type | Modifiers
-----------+---------+----------------------------------------------------------------------
id | integer | not null default nextval('spoleczniak_subskrypcje_id_seq'::regclass)
postac_id | integer | not null
tag_id | integer | not null
Indexes:
"spoleczniak_subskrypcje_pkey" PRIMARY KEY, btree (id)
"spoleczniak_subskrypcje_postac_id" btree (postac_id)
"spoleczniak_subskrypcje_postac_tag" btree (postac_id, tag_id)
"spoleczniak_subskrypcje_tag_id" btree (tag_id)
Foreign-key constraints:
"spoleczniak_subskrypcje_postac_id_fkey" FOREIGN KEY (postac_id) REFERENCES postac_postacie(id) DEFERRABLE INITIALLY DEFERRED
"spoleczniak_subskrypcje_tag_id_fkey" FOREIGN KEY (tag_id) REFERENCES spoleczniak_etykiety(id) DEFERRABLE INITIALLY DEFERRED
最佳答案
从查询计划来看,大部分时间似乎都涉及制定 where 子句的 IN 部分。似乎使用了适当的索引。
select o.wpis_id
from spoleczniak_oznaczone o
inner join spoleczniak_subskrypcje s on s.tag_id = o.etykieta_id
where s.postac_id = 376476
...看起来功能相同,但以不同的方式进行尝试并可能生成不同的查询计划。
此外,正如@wildplasser 所说,确保统计数据是最新的,并且对索引进行了碎片整理(我自己不知道如何在 PostgreSQL 中执行这些操作)。
编辑:正如@a_horse_with_no_name 在下面的评论中所说,我建议的查询可以返回原始查询不会返回的重复项。在不知道您的数据的情况下,我不知道它是否会。这是一个需要牢记的警告。
关于sql - PostgreSQL 中的查询优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22508931/