IBM DB2數(shù)據(jù)庫SQL編碼優(yōu)化的基礎(chǔ)教程經(jīng)典版!
以下的文章主要介紹的是IBM DB2數(shù)據(jù)庫SQL編碼優(yōu)化的基礎(chǔ)教程,這種特定查詢的重要性即為,查詢越重要,您可能就越應(yīng)該通過創(chuàng)建索引來對其進(jìn)行調(diào)優(yōu)。如果您正在編碼 CIO 要每天都運(yùn)行的查詢,那么您應(yīng)該確保它提供***性能。
因此,為該特定查詢構(gòu)建索引是很重要的。反之,職員的查詢也許就沒有必要看得那么重,所以也許應(yīng)該利用現(xiàn)有索引來執(zhí)行查詢。當(dāng)然,決定取決于應(yīng)用程序?qū)I(yè)務(wù)的重要性 - 而不只是用戶的重要性。
索引設(shè)計(jì)涉及的內(nèi)容比到目前為止我所討論的要多得多。例如,您也許要考慮索引重載以實(shí)現(xiàn)僅索引訪問(index-only access)。如果 SQL 查詢要尋找的所有數(shù)據(jù)都包含在索引中,那么 DB2 也許只使用索引就可以滿足該請求。請考慮我們前面的 SQL 語句。給定了關(guān)于 EMPNO 和 DEPTNO 的信息,我們要尋找 LASTNAME 和 SALARY。
我們還從創(chuàng)建關(guān)于 EMPNO 和 DEPTNO 列的索引開始。如果我們在索引中還包含了 LASTNAME 和 SALARY,我們就不再需要訪問 EMP 表,因?yàn)槲覀冃枰乃袛?shù)據(jù)都已經(jīng)在索引中。該技術(shù)可以大大提高性能,因?yàn)樗鼫p少了 I/O 請求的數(shù)量。
請記住:使每個查詢成為僅索引訪問是不謹(jǐn)慎,甚至也是不可能的。您應(yīng)該謹(jǐn)慎使用該技術(shù)以便用于特別棘手或重要的 SQL 語句。
SQL 編碼準(zhǔn)則
當(dāng)您編寫訪問 DB2 數(shù)據(jù)的 SQL 語句時(shí),要確保遵循以下三個編碼 SQL 的準(zhǔn)則以獲得***性能。當(dāng)然,SQL 性能是一個復(fù)雜的話題,而且了解 SQL 的執(zhí)行方式的每一個細(xì)微差別可能要花一生的時(shí)間。但是,這些簡單的規(guī)則可以使您進(jìn)入開發(fā)高性能 DB2 應(yīng)用程序的正軌。
***條規(guī)則是始終在每條 SQL SELECT 語句的 SELECT 列表中只提供 確實(shí)需要檢索的那些列 。另一種說法就是“不要使用 SELECT *”。簡寫 SELECT * 表示您要檢索正在被訪問的表中的所有列。這適用于“快捷但不恰當(dāng)?shù)姆绞将@得的“(quick and dirty)查詢,但卻是應(yīng)用程序的壞實(shí)踐,因?yàn)椋?/p>
DB2 表在將來可能需要更改,以包括附加列。SELECT * 也會檢索那些新的列,而如果沒有進(jìn)行費(fèi)時(shí)的更改,您的程序也許無法處理附加的數(shù)據(jù)。
DB2 將為被請求返回的每一列消耗附加資源。如果程序不需要數(shù)據(jù),它就不會尋找它。即使程序需要每一列,***根據(jù) SQL 語句中的名稱來顯式地尋找每一列,以便增加清晰度和避免以前犯的錯誤。
不要尋找您已經(jīng)知道的東西 。這聽起來似乎顯而易見,但大多數(shù)程序員都曾經(jīng)違反過這條規(guī)則。舉一個典型的示例,考慮以下 SQL 語句有什么錯誤:
- SELECT EMPNO, LASTNAME, SALARY
- FROM EMP
- WHERE EMPNO = ’000010’;
放棄嗎?問題是 EMPNO 已經(jīng)包含在 SELECT 列表中。您已經(jīng)知道了 EMPNO 將等于值“000010”,因?yàn)槟蔷褪?WHERE 子句要 DB2 做的事。但在 WHERE 子句中列出了 EMPNO,DB2 還會盡職地檢索該列。這會產(chǎn)生附加開銷,從而降低性能。
在 SQL 中 使用 WHERE 子句過濾數(shù)據(jù) ,而不是在程序中到處使用它進(jìn)行過濾。這也是新手容易犯的錯誤。在 DB2 將數(shù)據(jù)返回到程序之前,***由 DB2 過濾數(shù)據(jù)。這是因?yàn)?DB2 使用附加 I/O 和 CPU 資源來獲取每一行數(shù)據(jù)。傳遞到程序的行越少,SQL 的效率就越高:
- SELECT EMPNO, LASTNAME, SALARY
- FROM EMP
- WHERE SALARY > 50000.00;
與只讀取所有數(shù)據(jù)而不使用 WHERE 子句,然后在程序中檢查 SALARY 是否大于 50000.00 的做法相比,該 SQL 更好。
使用參數(shù)化查詢 。參數(shù)化 SQL 語句包含了變量,也稱作參數(shù)(或參數(shù)標(biāo)記)。典型的參數(shù)化查詢使用這些參數(shù)來代替文字值,因此 WHERE 子句條件可以在運(yùn)行時(shí)更改。通常程序被設(shè)計(jì)成最終用戶可以在運(yùn)行查詢之前提供參數(shù)的值。這允許使用一個查詢根據(jù)提供給參數(shù)的不同的值返回不同的結(jié)果。
參數(shù)化查詢的主要性能好處是優(yōu)化器可以制定在重復(fù)執(zhí)行語句時(shí)能夠再使用的存取路徑。與每次 WHERE 子句中需要一個新值就發(fā)出一條全新的 SQL 語句相比,這可以給程序增加很大的性能收益。
但是,這些規(guī)則并不是 SQL 性能調(diào)優(yōu)的最終和***目標(biāo) - 決不是。您可能需要附加的、深入的調(diào)優(yōu)。但遵循前面的規(guī)則將確保您不會犯降低應(yīng)用程序性能的“新手”錯誤。
特定IBM DB2數(shù)據(jù)庫應(yīng)用程序開發(fā)技巧
無論您使用的是 Delphi、C++Builder 還是 Kylix,某些技巧和準(zhǔn)則將幫助您確保在訪問 DB2 數(shù)據(jù)時(shí)獲得好的性能。例如,在某些情況下,使用 dbExpress TM來代替 ODBC/JDBC 或 ADO 可以提高查詢性能。dbExpress 是用于從 Delphi(或 Borland Kylix™)處理動態(tài) SQL 的跨平臺接口。
要確保在您的應(yīng)用程序中經(jīng)常發(fā)出 COMMIT 語句。COMMIT 語句控制工作單元。發(fā)出 COMMIT 會將自上一個 COMMIT 語句之后的所有工作“永遠(yuǎn)”記錄到IBM DB2數(shù)據(jù)庫中。在發(fā)出 COMMIT 之前,可以使用 ROLLBACK 語句回滾工作。
當(dāng)修改數(shù)據(jù)(使用 INSERT、UPDATE 和 DELETE)但沒有發(fā)出 COMMIT 時(shí),DB2 將在數(shù)據(jù)上加一把鎖并保持該鎖 - 這把鎖會使其它應(yīng)用程序在等待檢索被鎖住的數(shù)據(jù)時(shí)超時(shí)。通過在工作完成時(shí)發(fā)出 COMMIT 語句,并且確保數(shù)據(jù)是正確的,就釋放了該數(shù)據(jù)以供其它應(yīng)用程序使用。
另外,構(gòu)建應(yīng)用程序時(shí)要考慮使用情況。例如,當(dāng)某個特定查詢返回幾千行給最終用戶時(shí),要慎重處理。對于在程序和最終用戶之間的在線交互,很少會用到幾百行以上的數(shù)據(jù)。您可以在 SQL 語句上使用 FETCH FIRST nROWS ONLY 子句來限制返回到查詢的數(shù)據(jù)量。例如,考慮以下查詢:
- SELECT EMPNO, LASTNAME, SALARY
- FROM EMP
- WHERE SALARY > 10000.00
- FETCH FIRST 200 ROWS ONLY;
該查詢將只返回 200 行。如果有超過 200 行符合條件也沒有關(guān)系;如果您嘗試從查詢中 FETCH(訪存)超過 200 行,DB2 將用 +100 SQLCODE 表明數(shù)據(jù)結(jié)束。當(dāng)您想要限制返回給程序的數(shù)據(jù)量時(shí),這種方法很有用。
DB2 支持另一個名為 OPTIMIZE FOR nROWS 的子句,該子句不限制要返回給游標(biāo)的行數(shù),但從性能角度看可能是有幫助的。使用 OPTIMIZE FOR nROWS 子句告訴 DB2 如何處理 SQL 語句。例如:
- SELECT EMPNO, LASTNAME, SALARY
- FROM EMP
- WHERE SALARY > 10000.00
- OPTIMIZE FOR 20 ROWS;
這告訴 DB2 嘗試盡快訪存前 20 行。如果您的 Delphi 應(yīng)用程序在顯示從IBM DB2數(shù)據(jù)庫檢索出來的數(shù)據(jù)行時(shí)每次顯示 20 行,那么這將非常有用。
對于只讀游標(biāo),使用 FOR READ ONLY 子句確保游標(biāo)無歧義。Delphi 不能在 DB2 游標(biāo)中執(zhí)行位置更新,因此將 FOR READ ONLY 附加到每條 SELECT 語句后面可以使游標(biāo)成為無歧義的只讀游標(biāo),從而對 DB2 有所幫助。例如:
- SELECT EMPNO, LASTNAME, SALARY
- FROM EMP
- WHERE SALARY > 10000.00
- FOR READ ONLY;
結(jié)束語
了解 SQL 編碼以獲得***性能的基礎(chǔ)知識將使您的 Delphi 企業(yè)應(yīng)用程序的性能立即得到增長。但我只揭露了冰山一角。您需要學(xué)習(xí)日益增多的 SQL 的復(fù)雜類型,包括連接、子選擇和聯(lián)合等。您還需要學(xué)習(xí)如何***地編寫這些 SQL 語句以及如何發(fā)現(xiàn) DB2 選擇的存取路徑來滿足您的 SQL 請求。確實(shí),還有許多要學(xué)習(xí)。但是您已經(jīng)學(xué)習(xí)了一些如何***限度地利用 DB2 SQL 的初步知識,盡情地享用這些知識吧。
【編輯推薦】
- 3種DB2數(shù)據(jù)遷移的操作方案與其的缺點(diǎn)與注意事項(xiàng)
- 備份恢復(fù)DB2數(shù)據(jù)庫的3步驟,好用!
- DB2實(shí)施備份時(shí)應(yīng)作的事項(xiàng)有哪些?
- DB2數(shù)據(jù)庫的備份是否成功,一看就知道!
- DB2無限活動日志策略,從介紹到實(shí)際的操作技巧