2016-11-22 2 views
0

Я пишу веб-приложение, которое использует восемь запросов Postgres в довольно небольшой базе данных (около 300 записей). Существует только один запрос, который неоднократно неудовлетворительный. Мне кажется странным, что плохой запрос, который в основном ищет одну запись индексированным идентификационным номером, собирает различные поля, а затем выполняет одно соединение, медленнее, чем моя функция поиска, которая могла бы пройти через все 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 и прочитайте [ask] и [mcve]. – philipxy

+0

Я добавил DDL. – eabates

+0

0,1 секунды неудовлетворительно? Как быстро вам это нужно? И убедитесь, что вы [сохраняете] (http://stackoverflow.com/help/formatting) форматирование плана выполнения. Отказ шагов плана является важной информацией при чтении плана. –

ответ

0

Попробуйте выполнить запрос непосредственно в PostgreSQL с помощью PgAdmin. Также включают

EXPLAIN ANALYZE 
    <YourQuery> 

Таким образом, мы можем видеть план, созданный оптимизатором. Проверьте INDEX SEARCH(хорошо) или FULL SCAN(плохо)

Моя догадка у вас есть индекс для ID, но не для auth_id так LEFT JOIN медленно. Убедитесь, что у полей JOIN есть индекс

+1

, пожалуйста, обновите свой вопрос с этим информационным форматом в качестве кода, чтобы его было легко читать;) –

+1

. Ваше объяснение показывает «Seq Scan» от автора, что плохо, покажите нам вашу таблицу создания, чтобы увидеть, какой индекс создан, снова обновите свой вопрос , форматируйте как код и сообщите нам об обновлении в комментариях –

+0

Спасибо, я добавил таблицу create. Я сделал это в программном обеспечении Postico, которого я не могу делать в будущем, слишком много потери контроля. – eabates

Смежные вопросы