2014-01-30 85 views
1

我的任務是評估報告用SQL編寫的PostgreSQL數據庫報表查詢中加入額外表格的邊際成本。我被給了一個測試程序來測試查詢的性能。無論是否填充連接表,在運行時間之間似乎沒有統計學顯着差異。如何編寫更好的測試來說明兩種情況下查詢時間的差異?如何計算使用LEFT JOIN查詢附加表的成本?

在每種情況下,SQL都是相同的,將表A與表B連接在一起。唯一的區別是表B是否包含任何數據。

表A具有這些欄:

Column |   Type    
--------------+----------------------------- 
sid   | bigint      
cluster  | text       
sn   | text       
tag_id  | integer      
src_ip  | text       
dst_ip  | text       
dst_port  | integer      
protocol  | text       
src_intf  | text       
dst_intf  | text       
disp   | smallint      
rcvd_bytes | bigint      
sent_bytes | bigint      
duration  | integer      
count  | integer      
start_time | timestamp without time zone 
policy_id | text       
src_user  | text       
dst_domain | text       
app_id  | text       
signature_id | text       
deny_type_id | text       
reputation | text       
wb_cat_id | text       
alarm_name | text       
virus  | text       
sender  | text       
recipients | text       
host   | text       
dlp_rule_id | text       
spam_type | text       
spam_action | text       

表B具有這些欄:

兩個表由類型INET的IPv4地址接合。

測試數據填充表A和B,每個數據只有500多行。

隨着表B的填充,平均運行查詢的測試程序需要18.216秒的總運行時間。運行之間的標準偏差爲1.143秒。

在表B爲空的情況下,運行查詢的測試程序平均需要18.523秒的總運行時間。運行之間的標準偏差爲1.928秒。

每種情況下的樣本量是六次運行。我懷疑我需要使用更大的樣本量,但我不確定適合的樣本量是多少。

+1

第一個表中沒有* inet *列,它是如何連接的?而且每18秒加入500行都很慢,所以一定會有更復雜的事情發生。 PostgreSQL有沒有可能爲這些查詢獲得實際的CPU/IO使用情況,並將它們包括在比較中? – dnoeth

+0

表A較舊,**應**已使用inet,但使用IP地址的文本。報告測試程序首先用已知的一組數據填充表A,然後運行報告。我可能需要從測試程序中刪除一些代碼,如果結果是代碼沒有用處,那麼對測量查詢執行時間的目標沒有貢獻。 –

+0

如果這些表很小(500行),那麼使用正確的類型(連接類型inet和文本類型是showstopper ...)和正確的表結構,像這樣的查詢應該在10 ms左右完成。 – wildplasser

回答

1

我寫使用LEFT一個簡單的查詢JOIN:

SELECT * FROM a 
     LEFT JOIN b 
        ON a.src_ip::inet = b.ip 
        AND b.resolve_time IS NOT NULL AND b.resolve_time <= now() 
        AND b.expire_time IS NOT NULL AND now() < b.expire_time 

我然後跑100次迭代(查詢)的每10次測試和定時每個測試運行的結果。

下面是結果:

Query Run Times

通過平均運行時間和計算的運行時間與表B填充到填充而不表B的運行時間的比率,我能夠計算一個帶有表B的查詢在沒有查詢的情況下的開銷爲21.38%。