Postgresql

大表的不同計數太慢

  • September 4, 2019

我有一張有 12 億行的表。該表有 60-70 列,其中絕大多數是空的。

該表subscription_id在其他索引中被索引。

我的查詢是:

SELECT count(distinct listing_id)
FROM apps
WHERE subscription_id = 1298;

subscription_id將有大約 30M 行來計算。不幸的是,我無法這樣做,因為查詢需要超過一個小時才能獲得該計數。

我知道必須有一些方法來改進它。如果我同時創建一個索引會得到改進subscription_idlisting_id

如果我同時創建一個索引會得到改進subscription_idlisting_id

可能是的,(subscription_id, listing_id)(按此順序排列的列!)上的索引很可能允許更便宜的僅索引掃描。你沒有提供足夠的資訊來多說。

如果都是關於*這個特定subscription_id*的,那麼部分索引將有更多幫助:

CREATE INDEX ON apps (listing_id) WHERE subscription_id = 1298;

如果listing_id每個有多個重複項subscription_id,請將此改編後的查詢與遞歸 CTE 一起使用:

WITH RECURSIVE rcte AS (
  (
  SELECT listing_id
  FROM   apps
  WHERE  subscription_id = 1298
  ORDER  BY listing_id
  LIMIT  1
  )

  UNION ALL
  SELECT a.listing_id
  FROM   rcte r
  JOIN   LATERAL (
     SELECT a.listing_id
     FROM   apps a
     WHERE  a.subscription_id = 1298
     AND    a.listing_id > r.listing_id
     ORDER  BY a.listing_id
     LIMIT  1
     ) a ON a.listing_id IS NOT NULL
  )
SELECT count(*) FROM rcte;

要求上面的索引要快。對於許多重複,它可以快幾個數量級。關鍵是要解決仍然缺失的(直到 Postgres 12)索引跳過掃描。看:

如果, OTOH沒有重複listing_id, 則擺脫DISTINCT它以使其更快。

引用自:https://dba.stackexchange.com/questions/231758