簡體   English   中英

使用窗口功能加快慢速Postgres查詢

[英]Speed up slow Postgres query with window functions

我正在嘗試優化查詢,因為我的ORM(Django)生成的查詢導致超時。 我已經完成了ORM中所有可能的操作以將其作為一個查詢來運行,所以現在我想知道是否有任何Postgres技巧可以加快處理速度。

數據庫包含1m +和不斷增長的關系(id,源和目標),我需要對其進行過濾以排除源至少出現2次的連接。

這是當前查詢-“目標” ID的列表可能會增加,從而導致指數下降。

SELECT * FROM
(SELECT
    "source",
    "target",
    count("id") OVER (PARTITION BY "source") AS "count_match"
FROM
    "database_name"
WHERE
    ("database_name"."target" IN (123, 456, 789))
) AS temp_data WHERE "temp_data"."count_match" >= 2

我已經閱讀了有關VIEWS和臨時TABLES但是對於一次過的查詢而言,這似乎需要大量的設置和刪除。

編輯:更多信息和更高內存上的測試

解釋EXPLAIN ANALYSE結果:

Subquery Scan on alias_test  (cost=622312.29..728296.62 rows=1177604 width=24) (actual time=10245.731..18019.237 rows=1604749 loops=1)
  Filter: (alias_test.count_match >= 2)
  Rows Removed by Filter: 2002738
  ->  WindowAgg  (cost=622312.29..684136.48 rows=3532811 width=20) (actual time=10245.687..16887.428 rows=3607487 loops=1)
        ->  Sort  (cost=622312.29..631144.32 rows=3532811 width=20) (actual time=10245.630..12455.796 rows=3607487 loops=1)
              Sort Key: database_name.source
              Sort Method: external merge  Disk: 105792kB
              ->  Bitmap Heap Scan on database_name  (cost=60934.74..238076.96 rows=3532811 width=20) (actual time=352.529..1900.162 rows=3607487 loops=1)
                    Recheck Cond: (target = ANY ('{5495502,80455548,10129504,2052517,11564026,1509187,1981101,1410001}'::bigint[]))
                    Heap Blocks: exact=33716
                    ->  Bitmap Index Scan on database_name_target_426d2f46_uniq  (cost=0.00..60051.54 rows=3532811 width=0) (actual time=336.457..336.457 rows=3607487 loops=1)
                          Index Cond: (target = ANY ('{5495502,80455548,10129504,2052517,11564026,1509187,1981101,1410001}'::bigint[]))
Planning time: 0.288 ms
Execution time: 18318.194 ms

表結構:

    Column     |           Type           |                                     Modifiers
---------------+--------------------------+-----------------------------------------------------------------------------------
 created_date  | timestamp with time zone | not null
 modified_date | timestamp with time zone | not null
 id            | integer                  | not null default nextval('database_name_id_seq'::regclass)
 source        | bigint                   | not null
 target        | bigint                   | not null
 active        | boolean                  | not null
Indexes:
    "database_name_pkey" PRIMARY KEY, btree (id)
    "database_name_source_24c75675_uniq" btree (source)
    "database_name_target_426d2f46_uniq" btree (target)

硬件:

我嘗試將服務器功率增加到8GB內存實例,並使用PGTune中的以下內容更新了.conf文件:

max_connections = 10
shared_buffers = 2GB
effective_cache_size = 6GB
work_mem = 209715kB
maintenance_work_mem = 512MB
min_wal_size = 1GB
max_wal_size = 2GB
checkpoint_completion_target = 0.7
wal_buffers = 16MB
default_statistics_target = 100

盡管work_mem設置較高,但仍使用磁盤寫入進行合並,這令我感到困惑。 也許窗口功能導致了這種現象?

您的查詢已經是最佳的。 無法避免掃描整個表以獲取所需的信息,而順序掃描是做到這一點的最佳方法。

確保work_mem足夠大,以便可以在內存中完成聚合–您可以設置log_temp_files來監視是否使用了臨時文件(這會使速度變慢)。

暫無
暫無

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

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