【问题标题】:Increase query speed in PostgreSQL提高 PostgreSQL 中的查询速度
【发布时间】:2010-03-22 05:03:46
【问题描述】:

我的数据库查询时间很慢(到目前为止都在本地测试过),不知道该怎么做。数据库本身有 44 个表,其中一些表有超过 100 万条记录(主要是电影、女演员和演员表)。

该表是通过 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 吐出的。

您对如何提高速度有什么建议吗?

【问题讨论】:

  • 您能否(如果可能)对表格进行解释分析,以便我们确定成本是否准确?从查询中的行数来看,我预计您缺少索引。
  • 再次阅读您的查询后,我预计大部分减速都在title ILIKE '%Babe%' 部分。通过使用全文索引进行搜索,您可以“轻松”加快速度。
  • 您使用的是什么版本的 postgres?去年发布的 8.4 有一些显着的性能改进。

标签: sql postgresql performance


【解决方案1】:

这是你的问题:

" -> 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%”上使用任何索引,因此需要顺序扫描和巨大的成本。看看全文搜索,你可以创建一个适当的索引并让 queryplanner 使用它。

【讨论】:

    【解决方案2】:

    使用双端通配符(例如 '%Babe%')的查询无法利用任何索引,因此该表将导致顺序扫描而不是索引扫描。

    如果您正在搜索“Babe%”,那么您的索引应该可以工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-09
      • 2019-09-27
      • 2012-03-31
      • 2012-09-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多