为什么这个简单的SQL查询如此之慢?

时间:2015-05-13 08:49:51

标签: postgresql

我有一个查询

select p.id 
from Product p,Identifier i 
where p.id=i.product_id 
and p.aggregatorId='5109037' 
and p.deletionDate is null
and i.type='03' 
and i.value='9783639382891' 

运行大约需要3.5秒。产品有大约4.7米的条目,标识符大约20米。正如您在下面的模式中所看到的,查询中使用的每个列都已编制索引,但并未使用所有索引。如果我排除列p.aggregatorIdi.type,则查询运行速度与我预期的一样快。我也尝试加入标识符表,但解释计划没有变化。

为什么不使用索引?

解释计划如下:

Nested Loop  (cost=3.21..63.48 rows=1 width=33) (actual time=10.856..3236.830 rows=1 loops=1)
  ->  Index Scan using idx_prod_aggr on product p  (cost=0.43..2.45 rows=1 width=33) (actual time=0.041..191.339 rows=146692 loops=1)
        Index Cond: ((aggregatorid)::text = '5109037'::text)
        Filter: (deletiondate IS NULL)
  ->  Bitmap Heap Scan on identifier i  (cost=2.78..61.01 rows=1 width=33) (actual time=0.019..0.019 rows=0 loops=146692)
        Recheck Cond: ((product_id)::text = (p.id)::text)
        Filter: (((type)::text = '03'::text) AND ((value)::text = '9783639382891'::text))
        Rows Removed by Filter: 2"
        ->  Bitmap Index Scan on idx_id_prod_id  (cost=0.00..2.78 rows=29 width=0) (actual time=0.016..0.016 rows=2 loops=146692)
              Index Cond: ((product_id)::text = (p.id)::text)

简化的数据库架构如下所示:

CREATE TABLE product
(
  id character varying(32) NOT NULL,
  version integer,
  active boolean,
  aggregatorid character varying(15),
  deletiondate timestamp without time zone,
)
WITH (
  OIDS=FALSE
);

CREATE INDEX idx_prod_active
  ON product
  USING btree
  (active);

CREATE INDEX idx_prod_aggr
  ON product
  USING btree
  (aggregatorid COLLATE pg_catalog."default");

CREATE INDEX idx_prod_del_date
  ON product
  USING btree
  (deletiondate);



CREATE TABLE identifier
(
  id character varying(32) NOT NULL,
  version integer,
  typename character varying(50),
  type character varying(3) NOT NULL,
  value character varying(512) NOT NULL,
  product_id character varying(32),
  CONSTRAINT identifier_pkey PRIMARY KEY (id),
  CONSTRAINT fk165a88c9c93f3e7f FOREIGN KEY (product_id)
      REFERENCES product (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (
  OIDS=FALSE
);

CREATE INDEX idx_id_prod_type
  ON identifier
  USING btree
  (type COLLATE pg_catalog."default");

CREATE INDEX idx_id_prod_value
  ON identifier
  USING btree
  (value COLLATE pg_catalog."default");

CREATE INDEX idx_id_typename
  ON identifier
  USING btree
  (typename COLLATE pg_catalog."default");

CREATE INDEX idx_prod_ident
  ON identifier
  USING btree
  (product_id COLLATE pg_catalog."default");

0 个答案:

没有答案