簡體   English   中英

PostgreSQL:保留排序順序/臨時索引/分頁

[英]PostgreSQL: Retain Sort Order / Temporary Index / Paging

我正在使用PostgreSQL,打算分頁。 目標表包含1M +行。 原則上,這很簡單

SELECT * FROM myTable ORDER BY orderCol LIMIT <pageSize> OFFSET <offset>;

現在,在對orderCol編制索引時,此速度很快,但是在orderCol沒有索引時,速度較慢。 顯然,在最壞的情況下,dbms被迫執行全表掃描,並且必須對所請求的每個頁面的數據進行排序。

[ 編輯:更具體地說, orderCol可能會更改,即在運行時確定。

[ Edit2:索引orderCol改善排序性能的一般假設似乎是錯誤的。 如果我向orderCol添加索引,查詢時間將增加約70%。]

一種明顯的解決方案是根據需要創建一個具有適當索引的臨時表,並用適當的數據填充該表(…我認為)。 但這會復制所有數據。

有沒有一種方法可以“保留”請求之間的排序順序? 還是創建一個臨時索引?

非常感謝您提前答復。

好的,這是我想出的一種解決方案。

問題實際上是確定性行尋址和關系模型不兼容。 我基本上想做的就是告訴數據庫下一步要去哪里。 但是,由於請求彼此獨立,並且我們無法對表的物理結構進行任何假設,因此處理行的唯一方法是使用唯一的列值。

因此,以下解決方案:

CREATE TEMPORARY TABLE orderTable( id int, rank int );
CREATE INDEX orderIdx ON orderTable( rank );
INSERT INTO orderTable (
  select id, row_number() over (order by orderCol) as rank 
  from myTable ORDER BY orderCol
);

現在,我可以如下獲取頁面:

SELECT myTable.id, orderCol 
FROM myTable JOIN orderTable ON myTable.id=orderTable.id 
WHERE rank >= <lower> AND rank <= <upper>;

這聽起來乍看之下瘋狂,但對於約128頁尺寸是約一個相對於使用數量級decraesed查詢時間myTable與索引(和集群) orderCol

您遇到了幾個問題:

是的,對沒有索引的列進行排序很慢

您可能真的想索引所有可排序的列配置,至少是那些由您的應用程序經常排序的配置。 關於這個主題的一些有趣的見解寫在了這個博客中

偏移很慢

即使您有索引,跳轉到高頁碼的速度也很慢,因為您將不得不遍歷整個索引來進行OFFSET計數。 嘗試查看是否可以使用“搜索方法”

查找方法實質上跳到上一頁最后一條記錄之后的第一條記錄,例如

SELECT * 
FROM myTable 
WHERE orderCol > :lastValueforOrderCol
ORDER BY orderCol
LIMIT <pageSize>;

現在您不再需要按偏移量訪問記錄,而是通過使用謂詞,索引所有符合條件的orderCols至關重要。

請注意,此方法不允許您跳到固定順序位置,例如OFFSET 它的行為更像Twitter的“后續推文”的延遲加載。 這可能是可取的,也可能是不希望的。

注意,“搜索方法”也稱為鍵集分頁

全表掃描可能比索引掃描更快

由於您沒有任何謂詞,因此執行愚蠢的全表掃描並在內存中執行排序可能確實更快,而不是加載所有索引b樹節點(可能分散在磁盤上)以跳過行。 添加選擇謂詞后,這種觀察可能會逆轉。

不過,令我驚訝的是PostgreSQL的優化器不會自動選擇全表掃描。

是什么使您無法僅索引此列?

我有一個類似的問題,但是對於20GB / 40M +的行表,其中包含許多“ where”條件。 數據是靜態的,因此我讓DW Server運行每日腳本,該腳本僅提取了相關數據並創建了一個150k的表。

UPDATE

編輯:更具體地說,orderCol可能會更改,即在運行時確定

您是說每次有人運行查詢時,order列中的值都會更改(或者,column1,colume2,...可以是不同的列)?

調查具體化的視圖。 http://wiki.postgresql.org/wiki/Materialized_Views

您可以在此查詢上創建一個視圖,然后從該視圖運行所有查詢(並通過腳本每隔x分鍾/小時/天刪除它們)。 比臨時表容易得多。

除此之外,還有一些技巧取決於詳細的用例,但沒有現成的解決方案

暫無
暫無

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

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