【问题标题】:How can I optimize this SQL query in Postgres?如何在 Postgres 中优化此 SQL 查询?
【发布时间】:2013-05-29 17:22:56
【问题描述】:

我有一个包含近 100 万行的非常大的表,其中一些查询需要 很长 时间(超过一分钟)。

这是一个让我特别难过的事情......

EXPLAIN ANALYZE SELECT "apps".* FROM "apps" WHERE "apps"."kind" = 'software' ORDER BY itunes_release_date DESC, rating_count DESC LIMIT 12;
                                                           QUERY PLAN                                                            
---------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=153823.03..153823.03 rows=12 width=2091) (actual time=162681.166..162681.194 rows=12 loops=1)
   ->  Sort  (cost=153823.03..154234.66 rows=823260 width=2091) (actual time=162681.159..162681.169 rows=12 loops=1)
         Sort Key: itunes_release_date, rating_count
         Sort Method: top-N heapsort  Memory: 48kB
         ->  Seq Scan on apps  (cost=0.00..150048.41 rows=823260 width=2091) (actual time=0.718..161561.149 rows=808554 loops=1)
               Filter: (kind = 'software'::text)
 Total runtime: 162682.143 ms
(7 rows)

那么,我将如何优化它? PG 版本是 9.2.4,FWIW。

kindkind, itunes_release_date 上已有索引。

【问题讨论】:

  • 这不能回答你的问题,但如果你有 100 万条记录,你可能最好创建一个 app_kind 表,其中包含来自 apps 的数字引用,而不是重复 varchars,例如 @ 987654327@各地
  • @LukasEder:或者他可以使用枚举来保持现有查询不变。

标签: sql performance postgresql optimization


【解决方案1】:

看起来您缺少索引,例如在(kind, itunes_release_date desc, rating_count desc)

【讨论】:

  • kind 上的索引是否足够?不确定额外的列会加快排序速度。
  • 对 kind 的索引可能很有用,但仍会产生 top-n 排序。要使用索引直接获取前 12 名,OP 还需要在索引中添加(所有)排序列。
  • @AngerClown:该计划似乎表明 150k 行有kind = 'software',因此索引不会选择性过滤
  • @LukasEder 作为复合索引的一部分,它仍然可以提供帮助。
  • @LukasEder 该索引将有助于检索有限的行,而无需对整个表(或整个 150k 行)进行排序。
【解决方案2】:

apps 表有多大?你至少有这么多内存分配给 postgres 吗?如果每次都要从磁盘读取,查询速度会慢很多。

另一件可能有帮助的事情是将表聚集在“应用程序”列上。这可能会加快磁盘访问速度,因为所有software 行都将按顺序存储在磁盘上。

【讨论】:

  • 聚类不会有帮助,因为查询需要完全扫描和排序。 Postgres 内存分配可以提供帮助,但作用不大。
【解决方案3】:

加快此查询的唯一方法是在(itunes_release_date, rating_count) 上创建一个复合索引。它将允许 Postgres 直接从索引中选择前 N 行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多