2010-03-22 122 views
0

我在我的數據庫上遇到查詢時間很慢(到目前爲止所有的測試都在本地測試過),不知道該怎麼做。數據庫本身有44個表,其中一些表有超過100萬條記錄(主要是電影,女演員和演員表)。在PostgreSQL中提高查詢速度

該表是通過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吐出來了。

對於如何提高速度你有什麼建議嗎?

+0

您可以(如果可能的話)在桌面上運行解釋分析,以便我們確信成本是否準確?根據查詢中的行數來判斷,我希望你缺少一個索引。 – Wolph 2010-03-22 05:16:13

+0

再次閱讀您的查詢後,我預計大部分放緩都會出現在標題ILIKE'%Babe%'部分。通過使用全文索引進行搜索,您可以「很容易」將其提高很多。 – Wolph 2010-03-22 05:20:30

+0

你使用的是什麼版本的postgres?去年發佈的8.4具有顯着的性能改進。 – crowne 2010-03-22 05:26:47

回答

3

這是你的問題:

" -> 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))" 

順序掃描和巨大的成本,因爲該數據庫不能使用在「%貝貝%」任何指數。看看全文搜索,你可以創建一個合適的索引並讓查詢規劃者使用它。

2

使用雙端通配符(例如'%Babe%')的查詢無法利用任何索引,因此該表將導致順序掃描而不是索引掃描。

如果您正在搜索'寶貝%',那麼您的索引應該工作。