2016-11-22 63 views
0

我正在寫一個web應用程序,它在一個非常小的數據庫(大約300條記錄)上使用8個Postgres查詢。只有一個查詢反覆不能令人滿意。對我來說,這個看起來很奇怪的錯誤查詢,它通過索引ID號查找單個記錄,收集各種字段,然後執行單個連接,比我的搜索功能慢,這可能會經歷所有300條記錄(並且還執行聯合)。我是否誤解了疑問,或者有可能是一種索引方法來加速這種情況?緩慢的Postgres查詢,可能的索引修復?

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) 

我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.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) 
+0

請顯示您的DDL並閱讀[問]和[mcve]。 – philipxy

+0

我加了DDL。 – eabates

+0

0.1秒不滿意?你需要多快?請確保您[保存](http://stackoverflow.com/help/formatting)執行計劃的格式。計劃步驟的縮減是閱讀計劃時的重要信息 –

回答

0

嘗試使用pgAdmin的運行查詢,直接在PostgreSQL中。還包括

EXPLAIN ANALYZE 
    <YourQuery> 

所以我們可以看到優化器創建的計劃。檢查INDEX SEARCH(好)FULL SCAN(壞)

我的猜測是,你有指數ID而不是auth_id所以LEFT JOIN緩慢。請確保JOIN字段的索引爲

+1

請使用該信息格式作爲代碼更新您的問題,以使其易於閱讀;) –

+1

您的解釋顯示對作者不合適的Seq Scan,向我們展示您的創建表以查看創建了哪個索引,再次更新您的問題,格式爲代碼,並讓我們知道更新的意見 –

+0

謝謝,我添加了創建表。我在Postico軟件中做到了這一點,我可能在將來不會這樣做,太多的失控。 – eabates