意外的查询计划

时间:2016-12-05 01:48:20

标签: postgresql

我有一个带有7个UUID列的表“ps_wms.estoque”。 每列上都有一个sigle索引。 该表还在所有列上都有唯一索引。

create unique index idx on ps_wms.estoque (endereco_id, material_id, ..., origem_id);

下面的查询有一个where子句,它使用唯一索引中的所有列,但根据查询计划,它使用单个列的索引(列programacao_id),这是一个为所有记录保持相同值的列。在我看来,这个查询应该使用唯一索引,不应该吗?

select
    * 
from
    ps_wms.estoque a 
where
    a.endereco_id = '8d4d99b1-98f3-4768-bbdf-3768dc2be341'
    and a.material_id = '8d4d99b1-98f3-4768-bbdf-3768dc2be341' 
    and a.reserva_id = '8d4d99b1-98f3-4768-bbdf-3768dc2be341'
    and a.programacao_id = '8d4d99b1-98f3-4768-bbdf-3768dc2be341'
    and a.uma_id = '8d4d99b1-98f3-4768-bbdf-3768dc2be341'
    and a.tipo = '8d4d99b1-98f3-4768-bbdf-3768dc2be341'
    and a.origem_id = '8d4d99b1-98f3-4768-bbdf-3768dc2be341'

Index Scan using estoque_fk5 on ps_wms.estoque a
  Output: id, armazem_id, endereco_id, material_id, reserva_id, programacao_id, quantidade, version, uma_id, tipo, origem_id
  Index Cond: ((a.programacao_id)::uuid = '8d4d99b1-98f3-4768-bbdf-3768dc2be341'::uuid)
  Filter: (((a.endereco_id)::uuid = '8d4d99b1-98f3-4768-bbdf-3768dc2be341'::uuid) AND ((a.material_id)::uuid = '8d4d99b1-98f3-4768-bbdf-3768dc2be341'::uuid) AND ((a.reserva_id)::uuid = '8d4d99b1-98f3-4768-bbdf-3768dc2be341'::uuid) AND ((a.uma_id)::uuid = ' (...)

DDL

CREATE INDEX estoque_fk1 ON ps_wms.estoque (endereco_id);
CREATE INDEX estoque_fk2 ON ps_wms.estoque (material_id);
CREATE INDEX estoque_fk3 ON ps_wms.estoque (reserva_id);
CREATE INDEX estoque_fk4 ON ps_wms.estoque (armazem_id);
CREATE INDEX estoque_fk5 ON ps_wms.estoque (programacao_id);
CREATE INDEX estoque_fk6 ON ps_wms.estoque (uma_id);
CREATE INDEX estoque_fk7 ON ps_wms.estoque (origem_id);
CREATE UNIQUE INDEX iii ON ps_wms.estoque (endereco_id,material_id,reserva_id,programacao_id,uma_id,tipo,origem_id);

1 个答案:

答案 0 :(得分:1)

我弄清楚发生了什么。

我在where子句中使用的值是随机值。

由于'programacao_id'列只有一个所有行的值(n_distinct = 1),并且我在where子句中传递的值不是此值,引擎会根据此列提前知道此查询将返回空结果集。

如果我在where子句中使用实际值,则计划会按预期选择唯一索引。