2016-10-19 24 views
0

這裏是表結構爲什麼吐司表不影響擴展(分析)?

create table test as 
select 
    lpad('x',100,'x') as a1, 
    (SELECT array_to_string(ARRAY(SELECT chr((65 + round(random() * 25)):: int) FROM generate_series(1,1024*1024)), '')) as a2 
from generate_series(1,5*1024); 

表770KB加敬酒表的總大小5.8Gb

讓我們運行

explain (analyze, buffers, timing) select a2 from test 

"Seq Scan on t1 (cost=0.00..145.20 rows=5120 width=18) (actual time=0.041..2.959 rows=5120 loops=1)" 
"Buffers: shared hit=2 read=92" 
"Planning time: 1.771 ms" 
"Execution time: 3.375 ms" 

這意味着敬酒表進行掃描。這就是爲什麼解釋結果與實際查詢不匹配的原因。

我想這是一個規劃優化問題。沒有數據消費者,不需要閱讀它們。但是說明的結果,假設匹配(至少在時間上)到真正的查詢。

是關鍵字解釋,分析,緩衝語法的一部分,它們被插入到由postgres查詢解析器構建的AST中?或者他們從查詢中刪除,postgres執行查詢的其餘部分,但保持「精神」來獲取執行的統計細節?

如果有人可以確認或解釋它爲什麼發生。

回答

1

我不知道爲什麼選擇這樣做,但我想這是PostgreSQL試圖推遲detoasting一個值儘可能長時間的副作用。

你可能會迫使PostgreSQL相detoast它作爲查詢執行的一部分,這樣你會得到更真實的數據:

EXPLAIN (ANALYZE, BUFFERS, TIMING) SELECT length(a2) FROM test; 
+0

Detoast是可能的,但改變的輸出結果。這個查詢是原始的,這就是差異容易引人注目的原因。但是查詢的複雜性和數據傳播在表中並不固定。 – simar

+0

我想說問題只發生在查詢的'SELECT'列表中。無論如何,查詢中使用的所有中間值都必須被解除。所以只需在'SELECT'列表中的每個varlena列附加一個'length()'。 –