簡體   English   中英

PostgreSQL索引查詢速度不一致

[英]PostgreSQL index query speed inconsistency

我們在同一張表上有2個相同的(雙精度)列,其中2個相同的索引運行2個相同的查詢。 但是一個比另一個要快10倍。 是什么原因造成的?

1) SELECT MIN("reports"."longitude") AS min_id FROM "reports" WHERE (area2 = 18)

2) SELECT MIN("reports"."latitude") AS min_id FROM "reports" WHERE (area2 = 18)

1次以28ms運行,而2次以> 300ms運行

以下是“解釋”:
1)

Result  (cost=6.07..6.08 rows=1 width=0)"
InitPlan 1 (returns $0)"
  ->  Limit  (cost=0.00..6.07 rows=1 width=8)"
      ->  Index Scan using longitude on reports  (cost=0.00..139617.49 rows=22983 width=8)"
            Index Cond: (longitude IS NOT NULL)"
            Filter: (area2 = 18)"

2)

Result  (cost=5.95..5.96 rows=1 width=0)"
InitPlan 1 (returns $0)"
  ->  Limit  (cost=0.00..5.95 rows=1 width=8)"
      ->  Index Scan using latitude on reports  (cost=0.00..136754.07 rows=22983 width=8)"
            Index Cond: (latitude IS NOT NULL)"
            Filter: (area2 = 18)"

根據要求這里是解釋分析輸出...

1)

Result  (cost=6.07..6.08 rows=1 width=0) (actual time=10.992..10.993 rows=1 loops=1)"
InitPlan 1 (returns $0)"
    ->  Limit  (cost=0.00..6.07 rows=1 width=8) (actual time=10.985..10.986 rows=1 loops=1)"
          ->  Index Scan using longitude on reports  (cost=0.00..139617.49 rows=22983 width=8) (actual time=10.983..10.983 rows=1 loops=1)"
                Index Cond: (longitude IS NOT NULL)"
                Filter: (area2 = 18)"
Total runtime: 11.033 ms"

2)

 Result  (cost=5.95..5.96 rows=1 width=0) (actual time=259.749..259.749 rows=1 loops=1)"
InitPlan 1 (returns $0)"
    ->  Limit  (cost=0.00..5.95 rows=1 width=8) (actual time=259.740..259.740 rows=1 loops=1)"
          ->  Index Scan using latitude on reports  (cost=0.00..136754.07 rows=22983 width=8) (actual time=259.739..259.739 rows=1 loops=1)"
                Index Cond: (latitude IS NOT NULL)"
                Filter: (area2 = 18)"
Total runtime: 259.789 ms"
---------------------

到底是怎么回事? 如何使第二個查詢正常運行並快速運行? 據我所知,這兩種設置都是相同的。

首先,不能保證索引可以加快查詢速度。 其次,在考慮性能時,您需要多次運行每個查詢。 加載索引和將頁面加載到緩存中會產生開銷,這會影響查詢的長度。

我不是Postgres的專家,但是考慮到這一點,我並不感到驚訝。

查詢計划正在遍歷索引,找到與area2 = 18匹配的相應行,然后希望在第一個索引處停止(它正在使用索引,因此可以從最低值開始並向上移動)。 這是對其工作方式的猜測; 我不知道Postgres正是在這樣做。

無論如何,正在發生的事情是該區域比緯度索引的起點更接近經度索引的起點。 因此,它首先找到那里的第一個匹配記錄。 如果此解釋正確,則表明該區域與數據庫中的其他區域相比相對偏西(經度較低)和相對偏北(緯度較高)。

順便說一句,假設有很多區域,使用Area2上的索引可能會得到更好的結果。

您正在進行索引掃描,但是檢查的記錄數取決於要匹配area2條件必須走的列表的area2

除非您的area2分布很奇怪,否則要優化此查詢,應在(area2, latitude)(area2, longitude)上放置復合索引。 我懷疑您會得到<10毫秒。 PG還可以使用其位圖堆掃描功能將area2上的單獨索引與現有索引結合起來,以代替合成索引。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM