如何最有效地編寫SQL
解決數據庫級(SQL)工作上的問題,應該采用的是SET方法(整體的)而不是過程式的方法。下面來看看作者為什么這么說。
編寫有效的SQL查詢是企業軟件世界中***的難題之一。
每個公司在數據庫開發項目中所面臨的最根本的問題,在于開發環境中實現的性能不能在生產環境中實現。一般來說,存在性能損失是因為生產環境中的數據量要大得多。
這些問題(運行緩慢的數據庫操作)可能有各種各樣的原因。本文將解釋如何在編寫查詢時進行思考,如何思考是最基本的問題,也是解決此類問題的起點。
觀察發現SQL開發人員常使用過程方法編寫查詢。事實上,這是很自然的,因為用程序方法解決問題是最方便的人類邏輯解決方案。另一個方面,幾乎所有的SQL開發人員都在同時編寫Java、c#或其他編程語言的代碼。Java、C#等可以用來訓練開發人員以一種程序化的方式來培養他們的思維方式,因為當使用這些語言開發應用程序時,會使用很多類似的東西,比如IF .. THEN .. ELSE,FOR .. LOOP,WHILE .. DO, CASE .. WHEN。當然,在這種情況下,當將業務規則應用到一組數據時,意味著每個記錄都是單獨處理的(逐行處理)。這個過程方法在Java、c#等語言中使用。雖然使用語言開發軟件是一種正確的方法,但在編寫數據庫級(SQL)的查詢時,卻不會產生同樣的效果。
下面用兩種不同的方法來解決同一個示例問題,并將結果進行比較。看看CUSTOMERS表中對應的每個客戶在SALES表中有多少條記錄。
過程式方法如下:
現在,采用基于SET的方法來編寫查詢。
可以看到在兩個查詢的consistent gets數量之間的差異(當檢查緩沖區緩存讀到的塊數據時)是巨大的。使用兩種不同方法編寫的查詢在運行時導致不同時間。這種差別可以用性能來解釋。
在另一個例子中,常見的習慣是在SQL語句中調用PL/SQL函數。作為過程式工作的例子,也是一種解決問題的方法。還有其他一些影響在SQL內調用PL/SQL代碼性能的不利因素,但在本文中,不會提到性能問題。
下面編寫查找客戶表中每個客戶的購買金額的代碼。
過程方法:
在***步中,創建一個PL/SQL函數來計算每個客戶的總數,然后在代碼和輸出中調用這個函數。
現在,采用基于SET的方法來編寫查詢。
在本例中,通過查看consistent GETS和遞歸調用輸出,我們可以看到相同的情況。
我們的查詢也是生成更高效的數據庫操作的***步,它考慮的是批處理,而不是逐行思考。在進行數據庫操作時,批處理的方法會讓你在一天結束時消耗更少的資源,從而提高工作效率。