2011-07-07 60 views
3

我正在嘗試查找下面是否有詳細記錄的模式(或針對該問題的反模式)以減少應用程序延遲。我已經嘗試過這種技術,而且看起來這樣可以節省20%的延遲時間。我想知道是否有任何副作用會影響我應該知道的這是一個有據可查的模式嗎?

語境:

你已經有了一個方法/功能/過程,這使得對數據庫的多個選擇通話,你需要優化它。

可以說你的方法的流程是:

getDBConnection() 
    execute("Select a,b from tableA"); 
    bind a with varA 
    bind b with varB 
    ---SOME Business Logic----- 
    execute("Select c,d from tableB"); 
    bind c with varC 
    bind d with varD 
    ---SOME more Business Logic----- 
    execute("Select e,f from tableC"); 
    bind e with varE 
    bind f with varF 
    ---SOME more Business Logic----- 
    releaseConnection() 

解決方案: 使用UNION ALL進行一個調用數據庫

getDBConnection() 
execute("Select a,b,'sqlA' from tableA"+ 
" UNION ALL "+ 
" Select c,d,'sqlB' from tableB"+ 
" UNION ALL "+ 
"Select e,f,'sqlC' from tableC"); 
bind a,b where records have "sqlA" 
bind c,d where records have "sqlB" 
bind e,f where records have "sqlC" 
releaseConnection() 
--------Do all Business Logic here----- 

回答

6

採用union限制的「形」您的查詢。他們基本上都必須以相同的順序返回相同數量和(兼容)類型的列。

一個更好的方法將是一個命令使用多個查詢,然後用多個結果集處理:

execute("Select a,b from tableA;"+ 
    "Select c,d from tableB;"+ 
    "Select e,f from tableC"); 

或者可能創建一個運行這些查詢專用存儲過程。

除此之外,這種優化技術可以將不相關的操作集中在一起,這將限制以後各個操作的可重用性。您可能想要考慮一種更好地分離這些操作的設計,並使用某種QueryManager首先收集它們,然後再一起運行它們。

+1

+1「這種優化技術,不能一概而論不相干的操作,這將限制單個操作的可重用性以後」 –

+0

接受了它的QueryManager部分 – rajeshnair

1

將所有東西放在一起可能會掩蓋真正的問題:您是否知道延遲來自何處?

如果多次調用這些查詢,您可能會花費大量的時間在編譯階段。使用預處理語句可能會幫助,如果表格沒有您的應用程序的生命週期內太顯著改變:如果等待時間從編譯是不是可能是執行

conn = connect_to_db() 
pstmt = conn.prepare('select ...') 
... 
pstmt.bind(parameters) // if necessary 
pstmt.execute() 

- 你給的查詢是簡單的選擇,但更多的東西複雜可能需要檢查解釋計劃。

如果你的DBMS和你的表結構允許的話,一些重組也可能有助於削減需要多少查詢,可以這樣做:你可以結合使用的select語句加入,而不是某個工會嗎?你可以合併表與分區?

這就是一般的想法。爲了回答你的實際問題,我沒有看到過這種方法,但我不會讓惡名成爲唯一的決定性因素。正如前面的海報指出的那樣,你可能會犧牲代碼的可重用性。最後,隨着表的數量增長,這種方法不會很好地擴展:您仍然需要查找應用程序代碼中哪些行具有「sqlA」,具有「sqlB」等。

相關問題