sql - PostgreSQL 中的查询优化

标签 sql postgresql

我有一个相当简单的查询,总运行时间很大。你能告诉我如何优化它吗?

这是解释分析: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/

相关文章:

sql - 如何删除 SQL 中的重复项但保留一份副本?

postgresql - Postgres 9.6 仅索引扫描

sql - 为什么未使用的 FROM 表会使语句变慢

sql - 在 postgresql 中选择查询 >= jsonb 列值

sql - 如何在 MySQL 中最有效地获取两个日期时间值之间的 unix 时间戳间隔?

表中每一列的 SQL 循环

regex - 是否可以使用正则表达式对 PL/PGSQL 中的文本进行标记化?

python - Django ORM查询连接两个字段上不相关的表

php - PHP 页面中的多个 SQL 查询

sql - JOIN 当前行和上一行之间的范围