ABAP SQL編程規則
(1) SQL語句必須有一個WHERE子句,它只從數據庫中傳輸最小量的數據給應用服務器。對於所有從數據庫中傳輸數據或者傳輸給數據庫數據的程序:
Ø 如果程序對於表字段在SELECT…ENDSELECT循環中包含CHECK語句,那麼用合適的WHERE子句替換CHECK語句。
Ø 不帶有WHERE子句的SQL語句一定不能讀取一直增大的表,如BSEG、RESB。如果找到這樣的SQL語句,重寫這個程序。
Ø 避免同樣的讀取---也就是說,同樣的數據被重復的讀。要確定造成同樣的讀取SQL語句,用一個SQL跟蹤(TCODE:ST05)來跟蹤這個程序,瀏覽結果,並且選擇Goto.Idential selects。注意同樣的選擇,並且返回到跟蹤結果屏幕,查看這些選擇要求的多少時間。這會告訴你如果同樣的選擇可以避免的話,你將節省多少時間。
(2) 為了確保傳輸的數據量盡可能的小,按照下面描述的要點檢查程序。
Ø 帶有子句SELECT * 的SQL語句傳輸一個表的所有字段的內容。如果不是所有的這個數據都是真正需要的,就可以把SELECT * 子句轉換為一個SELECT LIST(SELECT )。
Ø 關於計算一個單個表的總和、最大值或者平均值使用SQL合計功能(SUM,MAX,AVG等等)。
(3) WHERE子句必須是簡單的;否則,優化器可 能會決定錯誤的索引或者根本就不使用索引。如果它使用AND和一個EQUALS條件來指明索引中每個字段的時候,一個WHERE子句就是簡單的。
Ø 實際上,當遇到大時的OR條件時候,所有的優化器都會有問題。因此,任何有可能的情況下都應當使用disjunct normal form. 。如下面代碼:
SELECT * FROM sflight WHERE (carrid = ‘LH’ or carrid = ‘UA’)
AND (CONNID = ‘0012’ OR CONNID = ‘0013’)
使用下面的代碼更好:
SELECT * FROM sflight
WHERE (carrud = ‘LH’ AND connid = ‘0012’)
OR (carrud = ‘LH’ AND connid = ‘0013’)
OR (carrud = ‘UA’ AND connid = ‘0012’)
OR (carrud = ‘UA’ AND connid = ‘0013’)
Ø 使用一個IN來替代一個OR。如,替代使用field1 = x1 and (field2 = y1 or field2 = y2 or field2 = y3),便用field1 = x1 and field2 in (y1 ,y2 , y3)。
Ø 盡量避免在WHERE子句中便用NOT條件。可以把一個NOT條件替換為一個正面的IN或OR條件,它們是使用索引可以處理的。
(4) fetches的數量必須保持很小。使用大批選擇而不是單個選擇來生成更少的,更長的數據庫讀取而不是許多短的讀取。可以通過使用FOR ALL ENTRIES子句把許多短小的讀取歸組為少數更長的讀取。當使用FOR ALL ENTRIES的時候,遵守下面的先決條件:
1. 驅動表必須不能為空。如果驅動表為空的,沒有數據,那麼FOR ALL ENTRIES子句將會讀取整個數據庫表。
2. 驅動表一定不能包含重復的記錄:如果驅動表包含重復記錄,則相應的數據 將會從數據庫中獲取兩次。
3. 註意:使用FOR ALL ENTRIES時,讀取出來的數據系統會去掉重復數據。
(5) 排序有兩種方法,一種是用SORT語句,排序操作在Application Server進行。另一種是在SELECT語句中使用ORDER BY ,排序操作在Database Server上進行。一般的處理方法是先將數據先存入內表,再用SORT進行排序,這種排序的性能比較好。但如果需要排序的數據量非常大,則用ORDER BY在DB Server進行排序性能比較好。
(6) 使用SELECT…INTO TABLE… 代替SELECT …ENDSELECT。
(7) 避免使用SELECT DISTINCT語句。使用的 ABAP SORT + DELETE ADJACENT DUPLICATES 代替。
(1) SQL語句必須有一個WHERE子句,它只從數據庫中傳輸最小量的數據給應用服務器。對於所有從數據庫中傳輸數據或者傳輸給數據庫數據的程序:
Ø 如果程序對於表字段在SELECT…ENDSELECT循環中包含CHECK語句,那麼用合適的WHERE子句替換CHECK語句。
Ø 不帶有WHERE子句的SQL語句一定不能讀取一直增大的表,如BSEG、RESB。如果找到這樣的SQL語句,重寫這個程序。
Ø 避免同樣的讀取---也就是說,同樣的數據被重復的讀。要確定造成同樣的讀取SQL語句,用一個SQL跟蹤(TCODE:ST05)來跟蹤這個程序,瀏覽結果,並且選擇Goto.Idential selects。注意同樣的選擇,並且返回到跟蹤結果屏幕,查看這些選擇要求的多少時間。這會告訴你如果同樣的選擇可以避免的話,你將節省多少時間。
(2) 為了確保傳輸的數據量盡可能的小,按照下面描述的要點檢查程序。
Ø 帶有子句SELECT * 的SQL語句傳輸一個表的所有字段的內容。如果不是所有的這個數據都是真正需要的,就可以把SELECT * 子句轉換為一個SELECT LIST(SELECT )。
Ø 關於計算一個單個表的總和、最大值或者平均值使用SQL合計功能(SUM,MAX,AVG等等)。
(3) WHERE子句必須是簡單的;否則,優化器可 能會決定錯誤的索引或者根本就不使用索引。如果它使用AND和一個EQUALS條件來指明索引中每個字段的時候,一個WHERE子句就是簡單的。
Ø 實際上,當遇到大時的OR條件時候,所有的優化器都會有問題。因此,任何有可能的情況下都應當使用disjunct normal form. 。如下面代碼:
SELECT * FROM sflight WHERE (carrid = ‘LH’ or carrid = ‘UA’)
AND (CONNID = ‘0012’ OR CONNID = ‘0013’)
使用下面的代碼更好:
SELECT * FROM sflight
WHERE (carrud = ‘LH’ AND connid = ‘0012’)
OR (carrud = ‘LH’ AND connid = ‘0013’)
OR (carrud = ‘UA’ AND connid = ‘0012’)
OR (carrud = ‘UA’ AND connid = ‘0013’)
Ø 使用一個IN來替代一個OR。如,替代使用field1 = x1 and (field2 = y1 or field2 = y2 or field2 = y3),便用field1 = x1 and field2 in (y1 ,y2 , y3)。
Ø 盡量避免在WHERE子句中便用NOT條件。可以把一個NOT條件替換為一個正面的IN或OR條件,它們是使用索引可以處理的。
(4) fetches的數量必須保持很小。使用大批選擇而不是單個選擇來生成更少的,更長的數據庫讀取而不是許多短的讀取。可以通過使用FOR ALL ENTRIES子句把許多短小的讀取歸組為少數更長的讀取。當使用FOR ALL ENTRIES的時候,遵守下面的先決條件:
1. 驅動表必須不能為空。如果驅動表為空的,沒有數據,那麼FOR ALL ENTRIES子句將會讀取整個數據庫表。
2. 驅動表一定不能包含重復的記錄:如果驅動表包含重復記錄,則相應的數據 將會從數據庫中獲取兩次。
3. 註意:使用FOR ALL ENTRIES時,讀取出來的數據系統會去掉重復數據。
(5) 排序有兩種方法,一種是用SORT語句,排序操作在Application Server進行。另一種是在SELECT語句中使用ORDER BY ,排序操作在Database Server上進行。一般的處理方法是先將數據先存入內表,再用SORT進行排序,這種排序的性能比較好。但如果需要排序的數據量非常大,則用ORDER BY在DB Server進行排序性能比較好。
(6) 使用SELECT…INTO TABLE… 代替SELECT …ENDSELECT。
(7) 避免使用SELECT DISTINCT語句。使用的 ABAP SORT + DELETE ADJACENT DUPLICATES 代替。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/23495244/viewspace-660059/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/23495244/viewspace-660059/