【问题标题】:'splain a postgresql EXPLAIN to me'向我解释一个 postgresql 解释
【发布时间】:2010-12-10 21:13:34
【问题描述】:

在这里得到这个查询:

EXPLAIN
SELECT persons.id AS id, ppm.first
FROM myschema.persons
INNER JOIN myotherschema.ppm ON persons.key = ppm.pid
WHERE persons.id = 279759;

ppm.pid 列是索引中的主键 AND:

CREATE INDEX ppm_pkey_index
  ON myotherschema.ppm
  USING btree
  (pid);

所以这里是解释:

Hash Join  (cost=8.31..3105.40 rows=306 width=23)
  Hash Cond: (textin(int4out(ppm.pid)) = persons.key)
  ->  Seq Scan on ppm  (cost=0.00..2711.33 rows=61233 width=23)
  ->  Hash  (cost=8.29..8.29 rows=1 width=12)
        ->  Index Scan using pskey on persons  (cost=0.00..8.29 rows=1 width=12)
              Index Cond: (id = 279759)

它似乎根本没有使用ppm_pkey_index:它似乎仍在扫描 61,233 行。为什么是这样?我误读了吗?推论:主键不是在 postgresql 中自动索引的吗?那么我的索引是多余的吗?

【问题讨论】:

  • 除非你的名字是 Ricky Riccardo,否则你应该避免使用“'splain”这个词。 (天哪,我老了。)
  • 我不需要向你们这样的人解释为什么 'splain 这么棒。

标签: sql postgresql sql-execution-plan


【解决方案1】:

主键在您的键上创建 UNIQUE INDEXES。所以你的索引确实是多余的。

创建索引后,您是否在表上运行了vacuum analyze

sql> vacuum analyze myotherschema.ppm;

我现在看到另一个问题:ppm.pidpersons.key 是否属于同一字段类型?由于不必要的数据转换,您可能会遇到性能问题,并且无法使用索引,因为您没有为连接时需要使用的转换函数编制索引...

【讨论】:

  • 啊,是的,persons.key 是 varchar,pid 是一个整数。将查询的连接更改为 "ON people.key::integer = ppm.pid" 是否有意义?很遗憾,我无法更改任何一种类型。
  • 成功了!我明确地投射了 key::integer 并且扫描消失了。谢谢!
  • 很棒的地方!我从来没有想过数据类型。
【解决方案2】:

如果将其更改为:

EXPLAIN
SELECT persons.id AS id, ppm.first
FROM myschema.persons
INNER JOIN myotherschema.ppm ON persons.id = 279759
AND persons.key = ppm.pid;

【讨论】:

  • 当然 postgres 有一个查询优化器,它足够聪明,无论你怎么写都能知道最快的路线?
  • 当查询跨模式时,查询优化器可能不会那么聪明?
  • @Paul Tomblin:优化器对不同模式或表空间中的表没有问题。
  • 这与 PostgreSQL 的查询完全相同,它将使用以下方法将两个查询展平为没有 JOIN 的表单:SELECT people.id AS id, ppm.first FROM myschema.persons, myotherschema.ppm WHERE 人。 id = 279759 AND people.key = ppm.pid;
  • 谢谢你澄清了,所有。我学到了一些新东西:-)
猜你喜欢
  • 1970-01-01
  • 2010-11-19
  • 1970-01-01
  • 2020-12-10
  • 2014-10-30
  • 2014-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多