慢Postgres查询,可能的索引修复?

时间:2016-11-22 01:40:37

标签: database postgresql relational-database node-postgres

我正在编写一个在很小的数据库(大约300条记录)上使用8个Postgres查询的Web应用程序。只有一个查询反复令人不满意。我觉得奇怪的是,错误的查询基本上通过索引的ID号查找单个记录,收集各种字段,然后执行单个连接,比我的搜索功能慢,可以想象通过所有300条记录(并且还执行连接)。我是否误解了查询,或者是否有一种索引方法可以加快这种情况?

    SELECT id, title, datepub, description, comments,               
           price, publisher, placepub, numberofimages, name 
    FROM book 
    LEFT JOIN author 
      ON book.author = author.auth_id 
    WHERE id=11003

以下是Postico创建表格的方式:

     CREATE TABLE author (
       auth_id integer NOT NULL,
       name character varying(250)
     );

     CREATE SEQUENCE author_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
     NO MAXVALUE
     CACHE 1;

     ALTER TABLE author_id_seq OWNER TO evanbates;
     ALTER SEQUENCE author_id_seq OWNED BY author.auth_id;

     ALTER TABLE ONLY author ALTER COLUMN auth_id SET DEFAULT  
     nextval('author_id_seq'::regclass);

     ALTER TABLE ONLY author
     ADD CONSTRAINT author_pkey PRIMARY KEY (auth_id);

我在作者上创建了索引:

     'CREATE UNIQUE INDEX author_pkey ON author USING btree (auth_id)'

我创建了书表:

     CREATE TABLE book (
     id integer NOT NULL,
     author integer,
     title text,
     subtitle text,
     datepub text,
     editiontext character varying(100),
     description text,
     comments text,
     bindingtext character varying(50),
     first boolean,
     dj boolean,
     signedtext boolean,
     isbn character varying(25),
     subject1 integer,
     subject2 integer,
     subject3 integer,
     subject4 integer,
     price numeric,
     location character varying(50),
     paid money,
     keyword1 text,
     bookcondition character varying(50),
     featured boolean,
     illustrator character varying(100),
     quantity smallint,
     dateadded date DEFAULT ('now'::text)::date,
     publisher character varying(100),
     placepub character varying(100),
     numberofimages smallint,
     imgurl text,
     hook character varying(75),
     display smallint DEFAULT '1'::smallint
);


     CREATE SEQUENCE book_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
     NO MAXVALUE
     CACHE 1;


     ALTER TABLE book_id_seq OWNER TO evanbates;
     ALTER SEQUENCE book_id_seq OWNED BY book.id;

     ALTER TABLE ONLY book ALTER COLUMN id SET DEFAULT       
     nextval('book_id_seq'::regclass);

     ALTER TABLE ONLY book
     ADD CONSTRAINT book_pkey PRIMARY KEY (id);

     ALTER TABLE ONLY book
     ADD CONSTRAINT book_author_fkey FOREIGN KEY (author) REFERENCES     
     author(auth_id);

     ALTER TABLE ONLY book
     ADD CONSTRAINT book_subject1_fkey FOREIGN KEY (subject1) REFERENCES    
     subject(subj_id);

     ALTER TABLE ONLY book
     ADD CONSTRAINT book_subject2_fkey FOREIGN KEY (subject2) REFERENCES   
     subject(subj_id);

     ALTER TABLE ONLY book
     ADD CONSTRAINT book_subject3_fkey FOREIGN KEY (subject3) REFERENCES    
     subject(subj_id);

     ALTER TABLE ONLY book
     ADD CONSTRAINT book_subject4_fkey FOREIGN KEY (subject4) REFERENCES   
     subject(subj_id);

我在书上有两个索引:

    CREATE UNIQUE INDEX book_pkey ON book USING btree (id)

    and

    CREATE INDEX first_idx ON book USING gin (title gin_trgm_ops)

我的解析分析是:

    Hash Right Join (cost=8.18..15.35 rows=1 width=426) (actual  time=0.089..0.093 rows=1 loops=1) 
      Hash Cond: (author.auth_id = book.author) 
      -> Seq Scan on author (cost=0.00..6.03 rows=303 width=33) (actual time=0.005..0.031 rows=304 loops=1) 
      -> Hash (cost=8.17..8.17 rows=1 width=401) (actual time=0.013..0.013 rows=1   
    loops=1) 
           Buckets: 1024 Batches: 1 Memory Usage: 9kB 
           -> Index Scan using book_pkey on book (cost=0.15..8.17 rows=1 width=401) (actual time=0.008..0.008 rows=1 loops=1) 
                Index Cond: (id = 11003)  

    Planning time: 0.213 ms 
    Execution time: 0.126 ms 
    (9 rows)

添加CREATE INDEX book_author_idx ON book USING btree (author)(见下文)后,我的EXPLAIN ANALYZE为:

   Hash Right Join  (cost=8.18..15.35 rows=1 width=426) (actual  time=0.089..0.093 rows=1 loops=1)
     Hash Cond: (author.auth_id = book.author)
     ->  Seq Scan on author  (cost=0.00..6.03 rows=303 width=33) (actual time=0.005..0.035 rows=304 loops=1)
     ->  Hash  (cost=8.17..8.17 rows=1 width=401) (actual time=0.012..0.012 rows=1 loops=1)
           Buckets: 1024  Batches: 1  Memory Usage: 9kB
           ->  Index Scan using book_pkey on book  (cost=0.15..8.17 rows=1 width=401) (actual time=0.008..0.009 rows=1 loops=1)
                Index Cond: (id = 11003)
   Planning time: 0.223 ms
   Execution time: 0.127 ms
   (9 rows)

1 个答案:

答案 0 :(得分:0)

尝试使用PgAdmin在postgresql中直接运行查询。还包括

  EXPLAIN ANALYZE
  <YourQuery>

所以我们可以看到优化器创建的计划。检查INDEX SEARCH (好)FULL SCAN (坏)

我的猜测是你有ID的索引但不是auth_id的索引,所以LEFT JOIN很慢。确保两个JOIN字段都有索引