Увеличьте скорость запросов в PostgreSQL - PullRequest
0 голосов
/ 22 марта 2010

Я испытываю медленное время запросов к моей базе данных (все протестированы локально до сих пор) и не знаю, как это сделать. Сама база данных содержит 44 таблицы, а некоторые из этих таблиц содержат более 1 миллиона записей (в основном таблицы фильмов, актрис и актеров).

Таблица составлена ​​через JMDB с использованием плоских файлов на IMDB. Кроме того, SQL-запрос, который я собираюсь показать, поступил от указанной программы (в ней также наблюдается очень медленное время поиска). Я попытался включить как можно больше информации, такой как план запроса и т. Д.

"QUERY PLAN"<br /> 
"HashAggregate  (cost=46492.52..46493.50 rows=98 width=46)"<br />
"  Output: public.movies.title, public.movies.movieid, public.movies.year"<br />
"  ->  Append  (cost=39094.17..46491.79 rows=98 width=46)"<br />
"        ->  HashAggregate  (cost=39094.17..39094.87 rows=70 width=46)"<br />
"              Output: public.movies.title, public.movies.movieid, public.movies.year"<br />
"              ->  Seq Scan on movies  (cost=0.00..39093.65 rows=70 width=46)"<br />
"                    Output: public.movies.title, public.movies.movieid, public.movies.year"<br />
"                    Filter: (((title)::text ~~* '%Babe%'::text) AND ((title)::text !~~* '""%}'::text))"<br />
"        ->  Nested Loop  (cost=0.00..7395.94 rows=28 width=46)"<br />
"              Output: public.movies.title, public.movies.movieid, public.movies.year"<br />
"              ->  Seq Scan on akatitles  (cost=0.00..7159.24 rows=28 width=4)"<br />
"                    Output: akatitles.movieid, akatitles.language, akatitles.title, <akatitles.addition"<br />
"                    Filter: (((title)::text ~~* '%Babe%'::text) AND ((title)::text !~~* '""%}'::text))"<br />
"              ->  Index Scan using movies_pkey on movies  (cost=0.00..8.44 rows=1 width=46)"<br />
"                    Output: public.movies.movieid, public.movies.title, public.movies.year, public.movies.imdbid"
"                    Index Cond: (public.movies.movieid = akatitles.movieid)"<br />

SELECT * FROM (
    (SELECT DISTINCT title, movieid, year 
    FROM movies 
    WHERE title ILIKE '%Babe%' AND NOT (title ILIKE '"%}'))
UNION
    (SELECT movies.title, movies.movieid, movies.year 
    FROM movies 
    INNER JOIN akatitles ON movies.movieid=akatitles.movieid 
    WHERE akatitles.title ILIKE '%Babe%' AND NOT (akatitles.title ILIKE '"%}'))
) AS union_tmp2;

Returns 612 Rows in 9078ms<br />
Database backup (plain text) is 1.61GB

Это действительно сложный запрос, и я не полностью осведомлен о нем, как я уже сказал, что его выплюнул JMDB.

Есть ли у вас какие-либо предложения о том, как я могу увеличить скорость?

Ответы [ 2 ]

3 голосов
/ 22 марта 2010

Это ваша проблема:

" -> Seq Scan on movies (cost=0.00..39093.65 rows=70 width=46)"
" Output: public.movies.title, public.movies.movieid, public.movies.year"
" Filter: (((title)::text ~~* '%Babe%'::text) AND ((title)::text !~~* '""%}'::text))"

Последовательное сканирование и огромные затраты, поскольку база данных не может использовать какой-либо индекс для «% Babe%». Посмотрите на полнотекстовый поиск, затем вы можете создать правильный индекс и позволить его использовать планировщику запросов.

2 голосов
/ 22 марта 2010

Запрос, который использует двусторонние символы подстановки (например, «% Babe%»), не может использовать какой-либо индекс, поэтому таблица будет выполнять последовательное сканирование вместо сканирования индекса.

Если вы искали 'Babe%', то ваш индекс должен работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...