在最基本的層面,包括選擇、插入、更新和刪除在內(nèi)的 SQL 操作是應(yīng)用程序與 DB2 數(shù)據(jù)庫進(jìn)行交互的方式。應(yīng)用程序的總體性能和體驗(yàn)受到該應(yīng)用程序所用的 SQL 操作的影響。 設(shè)計(jì)、維護(hù)、監(jiān)視和調(diào)優(yōu) SQL 查詢的完整處理超出了本文的范圍。然而,我們從較高層次概
在最基本的層面,包括選擇、插入、更新和刪除在內(nèi)的 sql 操作是應(yīng)用程序與 db2 進(jìn)行交互的方式。應(yīng)用程序的總體性能和體驗(yàn)受到該應(yīng)用程序所用的 sql 操作的影響。 設(shè)計(jì)、維護(hù)、監(jiān)視和調(diào)優(yōu) sql 查詢的完整處理超出了本文的范圍。然而,我們從較高層次概述了查詢設(shè)計(jì)的工具和一般準(zhǔn)則,因?yàn)椴樵冊O(shè)計(jì)和物理設(shè)計(jì)彼此密切相關(guān)。
大多數(shù)物理數(shù)據(jù)庫設(shè)計(jì)的特征對 SQL 語句并不明顯,但為了更好地使用 DB2 特性,在編寫查詢時(shí)需要考慮到數(shù)據(jù)庫的物理特征,如索引。例如,使用范圍分區(qū)表時(shí),選擇查詢即使沒有包含謂詞和范圍分區(qū)鍵,也仍然可以正常工作。然而,它可能沒有分區(qū)消除的性能優(yōu)勢。 另一方面,如果由于數(shù)據(jù)增長或其他任何原因,導(dǎo)致某個(gè) SQL 操作無法滿足業(yè)務(wù)服務(wù)水平協(xié)議,那么可能必須修改物理數(shù)據(jù)庫設(shè)計(jì)。物理數(shù)據(jù)庫設(shè)計(jì)變更的示例包括:增加索引、將常規(guī)表轉(zhuǎn)換為范圍分區(qū)表,或更改緩沖池的大小或關(guān)聯(lián),以達(dá)到預(yù)期的性能目標(biāo)。
OLTP 工作負(fù)載查詢
OLTP 工作負(fù)載中的查詢通常較短,涉及極少的表,并返回較小的結(jié)果集。不過,相比其他類型的工作負(fù)載,在 OLTP 工作負(fù)載中有更多并發(fā)查詢。 對于 OLTP 工作負(fù)載,設(shè)計(jì)可以快速返回結(jié)果的查詢對于獲得良好的性能是至關(guān)重要的。 此外,考慮到 OLTP 工作負(fù)載系統(tǒng)中一般有大量并發(fā)運(yùn)行的查詢。死鎖、因超時(shí)等待鎖定而回滾,甚至“死機(jī)”之類的事務(wù)可能會(huì)經(jīng)常發(fā)生。導(dǎo)致較少的死鎖和回滾的查詢設(shè)計(jì)可以使查詢性能有明顯差異。
OLTP 應(yīng)用程序?qū)τ谑褂梅秶指糁^詞的索引掃描是很好的候選者,因?yàn)樗鼈兺环祷貛讉€(gè)行,具有能夠?qū)σ粋€(gè)鍵列使用平等謂詞的資格。如果您的 OLTP 單查詢使用表掃描,您可能想對解釋設(shè)施 (explain facility) 數(shù)據(jù)進(jìn)行分析,以確定不使用索引掃描的原因。
隔離級別
DB2 數(shù)據(jù)庫管理器支持以下四種類型的隔離級別。它們按對性能的影響以降序排列,但在訪問和更新數(shù)據(jù)時(shí),它們需要的維護(hù)則是以升序排列的。
可重復(fù)讀 (RR)
RR 隔離級別將鎖定應(yīng)用程序在某個(gè)工作單元內(nèi)引用的所有行。使用此隔離級別,丟失更新、訪問未提交的數(shù)據(jù)和幻像行 (phantom row) 是不可能的。
讀穩(wěn)定性 (RS)
RS 隔離級別只鎖定應(yīng)用程序在工作單元內(nèi)檢索的那些行。
游標(biāo)穩(wěn)定性 (CS)
CS 隔離級別鎖定應(yīng)用程序的事務(wù)所訪問的任何行,同時(shí)將游標(biāo)定位到該行上。 未提交的讀 (UR) UR 隔離級別允許應(yīng)用程序訪問其他事務(wù)未提交的變更。未提交讀對只讀和可更新游標(biāo)的工作方式不同。
應(yīng)用程序死鎖
死鎖影響數(shù)據(jù)庫系統(tǒng)的性能。當(dāng)死鎖發(fā)生時(shí),數(shù)據(jù)庫管理器會(huì)選出要停止或回滾哪些事務(wù)(受害者)。這種影響會(huì)導(dǎo)致用戶獲得不好的體驗(yàn)。如果數(shù)據(jù)庫配置參數(shù)設(shè)置不正確,那么用戶可能會(huì)遇到停留在死鎖狀態(tài)的情況,最終可能需要數(shù)據(jù)庫管理員來解決死鎖。
當(dāng)您發(fā)出包含 WITH RELEASE 子句的 CLOSE CURSOR 語句來關(guān)閉游標(biāo)時(shí),數(shù)據(jù)庫管理器會(huì)嘗試釋放游標(biāo)持有的所有讀鎖。表讀鎖是 IS、S 和 U 表鎖。行讀鎖是 S、NS 和 U 行鎖。塊讀鎖是 IS、S 和 U 塊鎖。 WITH RELEASE 子句對在 CS 或 UR 隔離級別下操作的游標(biāo)沒有影響。對于在 RS 或 RR 隔離級別下操作的游標(biāo),WITH RELEASE 子句取消了這些隔離級別的部分保證。具體來說,一個(gè) RS 游標(biāo)可能會(huì)遇到不可重復(fù)讀現(xiàn)象,一個(gè) RR 游標(biāo)可能會(huì)遇到一個(gè)不可重復(fù)讀或幻讀。
如果在關(guān)閉原本在 RR 或 RS 隔離級別下操作的游標(biāo)后,您通過 WITH RELEASE 子句重新打開它,那么您會(huì)獲得新的讀鎖。 在某些情況下,在結(jié)果集關(guān)閉后會(huì)仍然保持鎖定,并且提交事務(wù)。如果在發(fā)出 COMMIT 語句之前關(guān)閉 CURSOR WITH HOLD,可以確保鎖定被釋放。即使在使用動(dòng)態(tài) SQL 的未提交讀應(yīng)用程序中,也會(huì)獲得目錄鎖。要釋放目錄鎖,請顯式發(fā)出 COMMIT 語句。
LOCK TABLE 語句鎖定整個(gè)表。只鎖定在 LOCK TABLE 語句中指定的表,沒有鎖定指定表的父表和依賴表。直到提交或回滾工作單元,才會(huì)釋放鎖定。您可以使用該語句防止鎖升級。您必須確定是否鎖定整個(gè)表及相關(guān)表是必要的,然后才能在并發(fā)性和性能方面實(shí)現(xiàn)想要的結(jié)果。