我在PostgreSQL中有一個transactions表,block_height和index為BIGINT值。這兩個值用于確定該表中事務的順序。
因此,如果我想從這個表中查詢在給定的block_height和index之后的事務,我必須把這個放在條件中
- 如果兩個事務處于相同的
block_height,那么檢查它們的index的順序 。
- 否則,比較它們的
block_height。
例如,如果我想得到10個在block_height 100000和index 5之后的交易:
SELECT * FROM transactions
WHERE (
(block_height = 10000 AND index >/span> 5)
OR (block_height > 10000)
)
ORDER BY block_height, index ASC >。
LIMIT10
但是我發現這個查詢非常慢,對于一個有5000萬行的表來說,它需要60秒。
然而,如果我把條件分割開來,并像這樣單獨運行它們:
SELECT * FROM transactions
WHERE block_height = 10000 AND index >/span> 5
ORDER BY block_height, index ASC
LIMIT10
并且
SELECT * FROM transactions
WHERE block_height >/span> 10000
ORDER BY block_height, index ASC
LIMIT10
這兩個查詢在同一個表上最多花費200ms! 做這兩個查詢,然后UNION最后的結果,而不是在條件中放一個OR,這要快得多。
這就是慢速查詢(OR-ed condition)的查詢計劃部分:
這就是慢速查詢的查詢計劃部分。
->嵌套回圈(cost=0。 98..11689726. 68 rows=68631 寬度=73)(實際time=10230。 480..10234. 289 rows=10 loops=1)
-> 索引掃描使用 src_transactions_block_height_index 對 src_transactions (cost=0。 56..3592792. 96 rows=16855334 width=73)(實際time=10215。 698..10219. 004 rows=1364 loops=1)
Filter: (((block_height = $1) AND (index > $2) OR (block_height > $3)
Rows 移除by Filter。2728151
這就是快速查詢的查詢計劃:
這就是快速查詢的查詢計劃。
-> 嵌套回圈(cost=0。 85..52. 62 rows=1 寬度=73)(實際time=0。 014..0. 014 rows=0 loops=1)
-> 索引掃描使用 src_transactions_block_height_index 對 src_transactions (cost=0。 43..22. 22 rows=5 寬度=73)(實際time=0。 014..0. 014 rows=0 loops=1)
索引條件: ((block_height = $1) and (index > $2)
我認為主要的區別是在查詢計劃之間使用Filter而不是Index Cond。
有沒有什么方法可以在不使用UNION作業方法的情況下,以一種高性能的方式完成這個查詢呢?
uj5u.com熱心網友回復:
事實上,block_height是與兩個不同的引數進行比較的,而你知道這兩個引數剛好是相等的,這可能是一個問題。 如果你使用1美元兩次,而不是1美元和3美元呢?
但更好的是,嘗試用元組比較
WHERE (block_height, index) >/span> (10000, 5)
這可以通過對(block_height, index)的雙列索引變得快速。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/324213.html
標籤:
