A. 通過分析SQL語句的執行計劃優化SQL(三)
第 章握拿SQL語句處理的過程 在調整之前我們需要了解一些背景知識 只有知道這些背景知識 我們才能更好的去調整sql語句 本節介紹了SQL語句處理的基本過程 主要包括 · 查詢語句處理 · DML語句處理(insert update delete) · DDL 語句處理(create drop alter ) · 事務控制(mit rollback) SQL 語句的執行過程(SQL Statement Execution) 圖 概要的列出了處理和運行一個sql語句的需要各個重要階段 在某些情況下 Oracle運行sql的過程可能與下面列出的各個階段的順序有所不同 如DEFINE階段可能在FETCH階段之前 這主要依賴你如何書寫代碼 對許多oracle的工具來說 其中某些階段會自動執行 絕大多數用戶不需要關心各個階段的細節問題 然而 知道執行的各個階段還是有必要的 這會幫助你寫出更高效的SQL語句來 而且還可以讓你猜測出性能差的SQL語句主要是由於哪一個階段造成的 然後我們針對這個具體的階段 找出解決的辦法 圖 SQL語句處理的各個階段 DML語句的處理 本節給出一個例子來說明在DML語句處理的各個階段到底發生了什麼事情 假設你使用Pro*C程序來為指定部門的所有職員增加工資 程序已經連到正確的用戶 你可以在你的程序中嵌入如下的SQL語句 EXEC SQL UPDATE employees SET salary = * salaryWHERE department_id = :var_department_id; var_department_id是程序變數 裡麵包含部畝配門號 我們要修改該部門的職員的工資 當這個SQL語句執行時 使用該變數的值 每種類型的語句都需要如下階段 · 第 步: Create a Cursor 創建游標· 第 步: Parse the Statement分析語句· 第 步: Bind Any Variables 綁定變數· 第 步: Run the Statement 運行語句· 第 步: Close the Cursor 關閉游標如果使用了並行功能 還會包含下面這個階段 · 第 步: Parallelize the Statement 並行執行語句段耐搭如果是查詢語句 則需要以下幾個額外的步驟 如圖 所示 · 第 步: Describe Results of a Query 描述查詢的結果集· 第 步: Define Output of a Query 定義查詢的輸出數據· 第 步: Fetch Rows of a Query 取查詢出來的行下面具體說一下每一步中都發生了什麼事情 第 步: 創建游標(Create a Cursor) 由程序介面調用創建一個游標(cursor) 任何SQL語句都會創建它 特別在運行DML語句時 都是自動創建游標的 不需要開發人員干預 多數應用中 游標的創建是自動的 然而 在預編譯程序(pro*c)中游標的創建 可能是隱含的 也可能顯式的創建 在存儲過程中也是這樣的 第 步:分析語句(Parse the Statement) 在語法分析期間 SQL語句從用戶進程傳送到Oracle SQL語句經語法分析後 SQL語句本身與分析的信息都被裝入到共享SQL區 在該階段中 可以解決許多類型的錯誤 語法分析分別執行下列操作 l 翻譯SQL語句 驗證它是合法的語句 即書寫正確l 實現數據字典的查找 以驗證是否符合表和列的定義l 在所要求的對象上獲取語法分析鎖 使得在語句的語法分析過程中不改變這些對象的定義l 驗證為存取所涉及的模式對象所需的許可權是否滿足l 決定此語句最佳的執行計劃l 將它裝入共享SQL區l 對分布的語句來說 把語句的全部或部分路由到包含所涉及數據的遠程節點 以上任何一步出現錯誤 都將導致語句報錯 中止執行 只有在共享池中不存在等價SQL語句的情況下 才對SQL語句作語法分析 在這種情況下 資料庫內核重新為該語句分配新的共享SQL區 並對語句進行語法分析 進行語法分析需要耗費較多的資源 所以要盡量避免進行語法分析 這是優化的技巧之一 語法分析階段包含了不管此語句將執行多少次 而只需分析一次的處理要求 Oracle只對每個SQL語句翻譯一次 在以後再次執行該語句時 只要該語句還在共享SQL區中 就可以避免對該語句重新進行語法分析 也就是此時可以直接使用其對應的執行計劃對數據進行存取 這主要是通過綁定變數(bind variable)實現的 也就是我們常說的共享SQL 後面會給出共享SQL的概念 雖然語法分析驗證了SQL語句的正確性 但語法分析只能識別在SQL語句執行之前所能發現的錯誤(如書寫錯誤 許可權不足等) 因此 有些錯誤通過語法分析是抓不到的 例如 在數據轉換中的錯誤或在數據中的錯(如企圖在主鍵中插入重復的值)以及死鎖等均是只有在語句執行階段期間才能遇到和報告的錯誤或情況 查詢語句的處理 查詢與其它類型的SQL語句不同 因為在成功執行後作為結果將返回數據 其它語句只是簡單地返回成功或失敗 而查詢則能返回一行或許多行數據 查詢的結果均採用表格形式 結果行被一次一行或者批量地被檢索出來 從這里我們可以得知批量的fetch數據可以降低網路開銷 所以批量的fetch也是優化的技巧之一 有些問題只與查詢處理相關 查詢不僅僅指SELECT語句 同樣也包括在其它SQL語句中的隱含查詢 例如 下面的每個語句都需要把查詢作為它執行的一部分 INSERT INTO table SELECT UPDATE table SET x = y WHERE DELETE FROM table WHERE CREATE table AS SELECT 具體來說 查詢· 要求讀一致性· 可能使用回滾段作中間處理· 可能要求SQL語句處理描述 定義和取數據階段 第 步: 描述查詢結果(Describe Results of a Query) 描述階段只有在查詢結果的各個列是未知時才需要 例如 當查詢由用戶交互地輸入需要輸出的列名 在這種情況要用描述階段來決定查詢結果的特徵(數據類型 長度和名字) 第 步: 定義查詢的輸出數據(Define Output of a Query) 在查詢的定義階段 你指定與查詢出的列值對應的接收變數的位置 大小和數據類型 這樣我們通過接收變數就可以得到查詢結果 如果必要的話 Oracle會自動實現數據類型的轉換 這是將接收變數的類型與對應的列類型相比較決定的 第 步: 綁定變數(Bind Any Variables) 此時 Oracle知道了SQL語句的意思 但仍沒有足夠的信息用於執行該語句 Oracle 需要得到在語句中列出的所有變數的值 在該例中 Oracle需要得到對department_id列進行限定的值 得到這個值的過程就叫綁定變數(binding variables)此過程稱之為將變數值捆綁進來 程序必須指出可以找到該數值的變數名(該變數被稱為捆綁變數 變數名實質上是一個內存地址 相當於指針) 應用的最終用戶可能並沒有發覺他們正在指定捆綁變數 因為Oracle 的程序可能只是簡單地指示他們輸入新的值 其實這一切都在程序中自動做了 因為你指定了變數名 在你再次執行之前無須重新捆綁變數 你可以改變綁定變數的值 而Oracle在每次執行時 僅僅使用內存地址來查找此值 如果Oracle 需要實現自動數據類型轉換的話(除非它們是隱含的或預設的) 你還必須對每個值指定數據類型和長度 關於這些信息可以參考oracle的相關文檔 如Oracle Call Interface Programmer s Guide 第 步: 並行執行語句(Parallelize the Statement ) ORACLE 可以在SELECTs INSERTs UPDATEs MERGEs DELETEs語句中執行相應並行查詢操作 對於某些DDL操作 如創建索引 用子查詢創建表 在分區表上的操作 也可以執行並行操作 並行化可以導致多個伺服器進程(oracle server processes)為同一個SQL語句工作 使該SQL語句可以快速完成 但是會耗費更多的資源 所以除非很有必要 否則不要使用並行查詢 第 步: 執行語句(Run the Statement) 到了現在這個時候 Oracle擁有所有需要的信息與資源 因此可以真正運行SQL語句了 如果該語句為SELECT查詢或INSERT語句 則不需要鎖定任何行 因為沒有數據需要被改變 然而 如果語句為UPDATE或DELETE語句 則該語句影響的所有行都被鎖定 防止該用戶提交或回滾之前 別的用戶對這些數據進行修改 這保證了數據的一致性 對於某些語句 你可以指定執行的次數 這稱為批處理(array processing) 指定執行N次 則綁定變數與定義變數被定義為大小為N的數組的開始位置 這種方法可以減少網路開銷 也是優化的技巧之一 第 步: 取出查詢的行(Fetch Rows of a Query) 在fetch階段 行數據被取出來 每個後續的存取操作檢索結果集中的下一行數據 直到最後一行被取出來 上面提到過 批量的fetch是優化的技巧之一 第 步: 關閉游標(Close the Cursor) SQL語句處理的最後一個階段就是關閉游標 DDL語句的處理(DDL Statement Processing) DDL語句的執行不同與DML語句和查詢語句的執行 這是因為DDL語句執行成功後需要對數據字典數據進行修改 對於DDL語句 語句的分析階段實際上包括分析 查找數據字典信息和執行 事務管理語句 會話管理語句 系統管理語句只有分析與執行階段 為了重新執行該語句 會重新分析與執行該語句 事務控制(Control of Transactions) 一般來說 只有使用ORACLE編程介面的應用設計人員才關心操作的類型 並把相關的操作組織在一起 形成一個事務 一般來說 我門必須定義事務 這樣在一個邏輯單元中的所有工作可以同時被提交或回滾 保證了數據的一致性 一個事務應該由邏輯單元中的所有必須部分組成 不應該多一個 也不應該少一個 · 在事務開始和結束的這段時間內 所有被引用表中的數據都應該在一致的狀態(或可以被回溯到一致的狀態)· 事務應該只包含可以對數據進行一致更改(one consistent change to the data)的SQL語句例如 在兩個帳號之間的轉帳(這是一個事務或邏輯工作單元) 應該包含從一個帳號中借錢(由一個SQL完成) 然後將借的錢存入另一個帳號(由另一個SQL完成) 這 個操作作為一個邏輯單元 應該同時成功或同時失敗 其它不相關的操作 如向一個帳戶中存錢 不應該包含在這個轉帳事務中 在設計應用時 除了需要決定哪種類型的操作組成一個事務外 還需要決定使用BEGIN_DISCRETE_TRANSACTIO存儲過程是否對提高小的 非分布式的事務的性能有作用 lishixin/Article/program/Oracle/201311/18806
B. 資料庫,數據結構,編譯原理對編程有那些影響和幫助
他們太重要了,
(1)數據結構:首先要明白---->程序=演算法+數據
「數據結構」就是做數據這塊的,例如一個「電影播放器」程序,首先要有「電影」嗎,這個就是「數據」,那麼就要用「數據結構」的知識,怎麼存儲每一幀,怎麼高效,怎麼能無損,怎麼空間最節省.........,然後才是怎麼去「解碼」(解碼就是「演算法」做的啦),當然這么講起來不是很嚴謹,但你可以看得出,數據結構可以說的上是有50%的重要性了。
(2)編譯原理:不要以為,自己不去開發「語言」,編譯原理就沒有用啦,它能讓你從根本上理解編譯器,這對怎麼提高程序的效率,怎麼變出漂亮的程序很有用................當然貌似如果從事,「人工智慧」這一塊的話,編譯原理也非常重要。
(3)資料庫:又是剛才哪一點----------->程序=演算法+數據
數據以文件的形式存儲,是在不是很高效,所以,為了方便數據的管理與查找等等..........人類作出了「資料庫」,說白了,它就是用來解決「數據」這部分內容的,現在基本無論你做什麼都離不開資料庫了,從大型網游到網站,到手機等的移動設備編程,都要用到資料庫
--------------------------------------------------------------------------------------------------
從你的體溫來看,你可能剛剛接觸編程,沒有做過什麼成品,隨著你越來越了解這個領域,你會剛到這些東西非常重要,當然還有很多東西,與以上三者地位相當,或更高,例如,微型計算機組成原理,等一些硬體方面的知識.......................................
---------------------------------------------------------------------------------------------------
還是「廣泛閱讀」吧。
C. sql語言用不用編譯
不用
將指令直接輸入其自帶的「查詢分析器」中運行就OK了
D. 嵌入式SQL的工作原理
提供對於嵌入式SQL的支持,需要資料庫廠商除了提供DBMS之外,還必須提供一些工具。為了實現對於嵌入式SQL的支持,技術上必須解決以下4個問題[1]: 1.宿主語言的編譯器不可能識別和接受SQL文,需要解決如何將SQL的宿主語言源代碼編譯成可執行碼;2.宿主語言的應用程序如何與DBMS之間傳遞數據和消息;3.如何把對數據的查詢結果逐次賦值給宿主語言程序中的變數以供其處理;4.資料庫的數據類型與宿主語言的數據類型有時不完全對應或等價,如何解決必要的數據類型轉換問題。 嵌入式SQL源碼的處理流程 為了解決上述這些問題,資料庫廠商需要提供一個嵌入式SQL的預編譯器,把包含有嵌入式SQL文的宿主語言源碼轉換成純宿主語言的代碼。這樣一來,源碼即可使用宿主語言對應的編譯器進行編譯。通常情況下,經過嵌入式SQL的預編譯之後,原有的嵌入式SQL會被轉換成一系列函數調用。因此,資料庫廠商還需要提供一系列函數庫,以確保鏈接器能夠把代碼中的函數調用與對應的實現鏈接起來。
E. 要學習SQL Server資料庫開發需要學習哪種資料庫開發語言和哪種資料庫開發工具呢
1、個人建議,掌握基本語句和利用好sqlsvr帶的查詢分析器工具,完全可以使用好資料庫。
表的建立
關系資料庫的主要特點之一就是用表的方式組織數據。表是SQL語言存放數據、查找數據以及更新數據的基本數據結叢返枯構。在SQL語言中,表有嚴格的定義,它是一種二維表,對於這種表有如下規定:
1)每一張表都有一個名字,通常稱為表名或關系名。表名必須以字母開頭,最大長度為30個字元。
2)一張表可以由若干列組成,列名唯一,列名也稱作屬性名。
3)表中的一行稱為一個元組,它相當於一條記錄。
4)同一列的數據必須具有相同的數據類型。
5)表中的每一個列值必須是不可分割的基本數據項。
注意:當用戶需要新的數據結構或表存放數據時,世雹首先要生成一個表。
語法:
CREATE TABLE 表名 [表約束]
(列名1 數據類型 [預設值1,列約束1]
(列名2 數據類型 [預設值2,列約束2]
…
列名n 數據類型 [預設值n,列約束n]
[TABLESPACE 表空間名稱]
[STORAGE (存貯的子句)]
[ENABLE 約束名]
[DISABLE 約束名]
插入數據
當一個表新建成時,它裡面沒有數據,通過向表中扦入數據,建成表的實例。
語句句法:
INSERT INTO 表名[(列名1,…)]
VALUES(值1,值2,…,值n)
修改數據
對表中已有數據進行修改,語句句法:
UPDATE 表名SET 列名1=表達式1,列名2=表達式2,…
WHERE 條件;
刪除數據
刪除表中已有數據,不能滲洞刪除不存在的數據。
語句句法:
DELETE FROM 表名 WHERE 條件;
查詢語句
SELECT命令的語法為:
SELECT [DISTINCT|ALL] *
FROM 表名
[WHERE條件]
[GROUP BY表達式[,表達式] …[HAVING條件]
[UNION|UNION ALL |INTERSECT|MINUS]SELECT命令
[ORDER BY{表達式|位置} [ASC|DESC] [, {表達式|位置[ASC|DESC]}]…]
2、資料庫開發語言:pb是一款比較不錯的資料庫開發語言,上手快,開發快捷。vb也可,上手容易。
3、linux不熟悉能學好Oracle,關聯不大,oracle也可在winxp環境使用。
F. SQL語句在資料庫中是怎樣執行的(sql怎麼執行語句)
第一步:應用程序把查枯運做詢SQL語句發給伺服器端執行
我們在數據層執行SQL語句時,應用程序會連接到相應的資料庫伺服器,把SQL語句發送給伺服器處理。
第二步:伺服器解析請求的SQL語句
SQL計劃緩存,經常用查詢分析器的朋友大概都知道這樣一個事實,往往一個查詢語句在第一次運行的時候需要執行特別長的時間,但是如果你馬上或悄絕者在一定時間內運行同樣的語句,會在很短的時間內返回查詢結果。原因是:
伺服器在接收到查詢請求後,並不會馬上去資料庫查詢,而是在資料庫中的計劃緩存中找是否有相對應的執行計劃。如果存在,就直接調用已經編譯好的執行計劃,節省了執行計劃的編譯時間。
如果所查詢的行已經存在於數據緩沖存儲區中,就不用查詢物理文件了,而是從緩存中取數據,這樣從內存中取數據就會比從硬碟上讀取數據快很多,提高了查詢效率。數據緩沖存儲區會在後面提到。
如果在SQL計劃緩存中沒有對應的執行計劃,伺服器首先會對用戶請求的SQL語句進行語法效驗,如果有語法錯誤,伺服器會結束查詢操作,並用返回相應的錯誤信息給調用它的應用程序。
注意:此時返回的錯誤信息中,只會包含基本的語法錯誤信息,例如select寫成selec等,錯誤信息中如果包含一列表中本沒有的列,此時伺服器是不會檢查出來的,因為只是語法驗證,語義是否正確放在下一步進行。
語法符合後,就開始驗證它的語義是否正確。例如,表名、列名、存儲過程等等資料庫對象是否真正存在,如果發現有不存在的,就會報錯給應用程序,同時結束查詢。
接下來就是獲得對象的解析鎖,我們在查詢一個表時,首先伺服器會對這個對象加鎖,這是為了保證數據的統一性,如果不加鎖,此時有數據插入,但因為沒有加鎖的原因,查詢已經將這條記錄讀入,而有的插入會因為事務的失敗會回滾,就會形成臟讀的現象。
接下來就是對資料庫用戶許可權的驗證。SQL語句語法,語義都正確,此時並不一定能夠得到查詢結果,如果資料庫用戶沒有相應的訪問許可權,伺服器會報出許可權不足的錯誤給應用程序,在稍大的項目中,往往一個項目裡面會包含好幾個資料庫連接串,這些資料庫用戶具有不同的許可權,有的是只讀許可權,有的是只寫許可權,有的是可讀可寫,根據不同的操作選取不同的用戶來執行。稍微不注意,無論你的SQL語句寫的多麼完善,完美無缺都沒用。
解析的最後一步,就是確定最終的執行計劃。當語法、語義、許可權都驗證後,伺服器並不會馬上給你返回結果,而是會針對你的SQL進行優化,選擇不同的查詢演算法以最高效的形式返回給應用程序。例如在做表聯合查詢時,伺服器會根據開沒衡銷成本來最終決定採用hashjoin,mergejoin,還是loopjoin,採用哪一個索引會更高效等等。不過它的自動化優化是有限的,要想寫出高效的查詢SQL還是要優化自己的SQL查詢語句。
當確定好執行計劃後,就會把這個執行計劃保存到SQL計劃緩存中,下次在有相同的執行請求時,就直接從計劃緩存中取,避免重新編譯執行計劃。
第三步:語句執行
伺服器對SQL語句解析完成後,伺服器才會知道這條語句到底表態了什麼意思,接下來才會真正的執行SQL語句。
此時分兩種情況:
如果查詢語句所包含的數據行已經讀取到數據緩沖存儲區的話,伺服器會直接從數據緩沖存儲區中讀取數據返回給應用程序,避免了從物理文件中讀取,提高查詢速度。
如果數據行沒有在數據緩沖存儲區中,則會從物理文件中讀取記錄返回給應用程序,同時把數據行寫入數據緩沖存儲區中,供下次使用。
說明:SQL緩存分好幾種,這里有興趣的朋友可以去搜索一下。有時因為緩存的存在,使得我們很難馬上看出優化的結果,因為第二次執行因為有緩存的存在,會特別快速,所以一般都是先消除緩存,然後比較優化前後的性能表現,這里有幾個常用的方法:
1DBCC
2從緩沖池中刪除所有清除緩沖區。
3DBCC
4從過程緩存中刪除所有元素。
5DBCC
6從所有緩存中釋放所有未使用的緩存條目。
SQLServer2005資料庫引擎會事先在後台清理未使用的緩存條目,以使內存可用於當前條目。但是,可以使用此命令從所有緩存中手動刪除未使用的條目。
這只能基本消除SQL緩存的影響,目前好像沒有完全消除緩存的方案,如果大家有,請指教。
執行順序:
FROM子句返回初始結果集。
WHERE子句排除不滿足搜索條件的行。
GROUPBY子句將選定的行收集到GROUPBY子句中各個唯一值的組中。
選擇列表中指定的聚合函數可以計算各組的匯總值。
此外,HAVING子句排除不滿足搜索條件的行。
計算所有的表達式;
使用orderby對結果集進行排序。
查找你要搜索的欄位。
G. 資料庫開發需要學什麼
資料庫開發工程師需要學習的課程有:
1、計算機導論
內容提要:為新學生提供一個關於計算機科學與技術學科的入門介紹,使他們對該學科有一個整體的認識,並了解該專業的學生應具有的基本知識和技能以及在該領域工作應有的職業道德與應遵守的法律准則。
2、數字電路與數字邏輯
內容提要:介紹數字邏輯與數字系統的基本概念、分析方法和設計原理,包括開關理論基礎、組合邏輯、時序邏輯、可編程邏輯器件、數字系統等。
3、計算機組成原理與匯編語言
內容提要:以馮諾依曼計算機模型為出發點,介紹計算機的組織結構和工作原理,剖析計算機的運算器、存儲器、控制器和輸入輸出設備的結構、工作原理和相互關系;介紹80X86指令系統、匯編語言與匯編指令、匯編程序與匯編過程、簡單匯編程序設計、匯編語言與高級語言的介面、宏匯編等。
4、計算機網路
內容提要:介紹數據通信的基本概念和計算機網路的基本原理,包括計算機網路的體系結構、數據通信的基本方法和協議、計算機網路的主要應用協議;同時介紹計算機網路系統的安全和管理知識,使學生對數據通信和計算機網路有一個全面理解。
5、計算機體系結構
內容提要:研究計算機系統結構的基本概念、基本原理、基本結構和基本分析方法,使同學在具有一定的軟硬體知識基礎上能綜合認識計算機系統余襲的軟硬體功能分配與各種不同結構類型機器的特性和性能評價方法。為研究、開發、應用高級計算機系統打下基礎。確立全面、系統的觀點和學會定量分析問題的方法。
6、離散數學
內容提要:包括集合論、數理邏輯、圖論、組合數學等內容,形式化的數學證明貫穿此課程。
7、高級程序設計語言
內容提要:分別以C、C#或JAVA為例,介紹程序設計和語言,程序的基本數據結構、類型定義、簡單類型和結構化類型、程序的基本控制結構、結構化程序設計、面向對象的程序設計等。
8、演算法分析與設計
內容提要:本課程延續數據結構課程的學習,從演算法分析和設計的角度出發,除去傳統的分類查找演算法和一般的設計方法外,主要內容包括如下幾個部分:演算法研究的理論基礎,遞歸分析技術,基本演算法設計策略(幾類經典演算法學習),多項式運算與FFT,串匹配,概率分析演算法橘毀昌。希望通過這一課程的學習,使學生能對現代的演算法設計及分析的基本工具能有較全面的掌握。
9、數據結構
內容提要:介紹線性表及其鏈接存儲結構與演算法、數組與矩陣、堆棧與隊列、廣義表的存儲結構與多元多項式表示、串與文本編輯、排序、樹、圖、文件結構。
10、資料庫系統原理
內容提要:介紹資料庫系統的基本概念、原理、方法及應用,主要包括資料庫系統概論、資料庫管理系統實現技術、資料庫存儲結構及其他類型的資料庫系統。
11、編譯技術
內容提要:介紹編譯原理的理論和實踐,包括編譯程序設計、詞法分析、語法分析、符號表、聲明和存儲管理、代碼生成以及優化技術。
12、操作系統
內容提要:介紹操作系統的設計與實現,包括操作系統各組成部分的概述、互斥性和同步性、處理器實現、調度演算法、存儲演算法、設備管理和文件系統。
資料庫開發工程師是指設計、開發、維護管理大型資料庫的專業人才。
第一類是MySQL,以自由軟體為主,以社團式開發為代表。版本選擇4.0,側重於在Linux平台(RedHat8.0)。MySQL資料庫短小精悍,速度比較快,它是自由軟體產品,現在美國國家航天局的資料庫系統就是MySQL。在很多中小型的ICP有著廣泛的應用。
第二類是SQLServer2000,中小型企業資料庫,界面友好,可操作性強,在資料庫市場佔有很大的份量,SQLServer2000是圓扒企業產品的代表,定位資料庫中低端市場。
第三類是Oracle9i,中大型企業資料庫,跨平台,在資料庫中高市場佔有很大的份量,Oracle9i介紹主要是Windows2000平台和Linux平台(RedHat8.0)。Oracle9i在金融、電信、銀行有很多經典應用。
資料庫開發需要學習數據結構與演算法,操作系統程序,語言開發,資料庫知識,基礎知識,SQL語言數據流程,設置資料庫系統的運行和管理。光寫資料庫開發還不行,還得要搭配一門開發語言,只有開發語言了,結合資料庫開發才是一個合格的程序員。開發語言建議你學Java或者是PhP。
H. 做後端開發需要學什麼
對於初學Java並且有志於後端開發的同學來說,需要重點關注以下幾個部分:
基礎:比如計算機系統、演算法、編譯原理等等
Web開發: 主要是Web開發相關的內容,包括HTML/CSS/js(前端頁面)、 Servlet/JSP(J2EE)以及MySQL(資料庫)相關的知識。它們的學習順序應該是從前到後,因此最先學習的應該是HTML/CSS/JS(前端頁面)。
J2EE:你需要學習的是Servlet/JSP(J2EE)部分,這部分是Java後端開發必須非常精通的部分,因此這部分是這三部分中最需要花精力的。關於Servlet/Jsp部分視頻的選擇,業界比較認可馬士兵的視頻。
最後一步,你需要學會使用資料庫,彎態激mysql是個不錯的入門選擇,而且Java領域里主流的關系型資料庫就是mysql。這部分一般在你學習Servlet/Jsp的時候,就會接觸閉燃到的,其中的JDBC部分就是資料庫相關的部分。你不僅要學會使用JDBC操作數埋襪據庫,還要學會使用資料庫客戶端工具,比如navicat,sqlyog,二選一即可。
開發框架:目前比較主流的是SSM框架,即spring、springmvc、mybatis。你需要學會這三個框架的搭建,並用它們做出一個簡單的增刪改查的Web項目。你可以不理解那些配置都是什麼含義,以及為什麼要這么做,這些留著後面你去了解。但你一定要可以快速的利用它們三個搭建出一個Web框架,你可以記錄下你第一次搭建的過程,相信我,你一定會用到的。還要提一句的是,你在搭建SSM的過程中,可能會經常接觸到一個叫maven的工具。這個工具也是你以後工作當中幾乎是必須要使用的工具,所以你在搭建SSM的過程中,也可以順便了解一下maven的知識。在你目前這個階段,你只需要在網路上了解一下maven基本的使用方法即可,一些高端的用法隨著你工作經驗的增加,會逐漸接觸到的。
總而言之,這個階段,你需要做的是深入了解Java底層和Java類庫,也就是JVM和JDK的相關內容。而且還要更深入的去了解你所使用的框架,方式比較推薦看源碼或者看官方文檔。
I. SQL語句執行過程詳解
SQL語句執行過程詳解
一條sql,plsql的執行到底是怎樣執行的呢?
一、SQL語句執行原理:
第一步:客戶端把語句發給伺服器端執行當我們在客戶端執行 select 語句時,客戶端會把這條 SQL 語句發送給伺服器端,讓伺服器端的
進程來處理這語句。也就是說,Oracle 客戶端是不會做任何的操作,他的主要任務就是把客戶端產生
的一些 SQL 語句發送給伺服器端。雖然在客戶端也有一個資料庫進程,但是,這個進程的作用跟伺服器
上的進程作用事不相同的。伺服器上的資料庫進程才會對SQL 語句進行相關的處理。不過,有個問題需
要說明,就是客戶端的進程跟伺服器的進程是一一對應的。也就是說,在客戶端連接上伺服器後,在客戶
端與伺服器端都會形成一個進程,客戶端上的我們叫做客戶端進程;而伺服器上的我們叫做伺服器進程。
第二步:語句解析
當客戶端把 SQL 語句傳送到伺服器後,伺服器進程會對該語句進行解析。同理,這個解析的工作,
也是在伺服器端所進行的。雖然這只是一個解析的動作,但是,其會做很多「小動作」。
1. 查詢高速緩存(library cache)。伺服器進程在接到客戶端傳送過來的 SQL 語句時,不
會直接去資料庫查詢。而是會先在資料庫的高速緩存中去查找,是否存在相同語句的執行計劃。如果在
數據高速緩存中,則伺服器進程就會直接執行這個 SQL 語句,省去後續的工作。所以,採用高速數據緩
存的話,可以提高 SQL 語句的查詢效率。一方面是從內存中讀取數據要比從硬碟中的數據文件中讀取
數據效率要高,另一方面,也是因為這個語句解析的原因。
不過這里要注意一點,這個數據緩存跟有些客戶端軟體的數據緩存是兩碼事。有些客戶端軟體為了
提高查詢效率,會在應用軟體的客戶端設置數據緩存。由於這些數據緩存的存在,可以提高客戶端應用軟
件的查詢效率。但是,若其他人在伺服器進行了相關的修改,由於應用軟體數據緩存的存在,導致修改的
數據不能及時反映到客戶端上。從這也可以看出,應用軟體的數據緩存跟資料庫伺服器的高速數據緩存
不是一碼事。
2. 語句合法性檢查(data dict cache)。當在高速緩存中找不到對應的 SQL 語句時,則服
務器進程就會開始檢查這條語句的合法性。這里主要是對 SQL 語句的語法進行檢查,看看其是否合乎
語法規則。如果伺服器進程認為這條 SQL 語句不符合語法規則的時候,就會把這個錯誤信息,反饋給客
戶端。在這個語法檢查的過程中,不會對 SQL 語句中所包含的表名、列名等等進行 SQL 他只是語法
上的檢查。
3. 語言含義檢查(data dict cache)。若 SQL 語句符合語法上的定義的話,則伺服器進程
接下去會對語句中的欄位、表等內容進行檢查。看看這些欄位、表是否在資料庫中。如果表名與列名不
准確的話,則資料庫會就會反饋錯誤信息給客戶端。所以,有時候我們寫 select 語句的時候,若語法
與表名或者列名同時寫錯的話,則系統是先提示說語法錯誤,等到語法完全正確後,再提示說列名或表名
錯誤。
4. 獲得對象解析鎖(control structer)。當語法、語義都正確後,系統就會對我們需要查詢
的對象加鎖。這主要是為了保障數據的一致性,防止我們在查詢的過程中,其他用戶對這個對象的結構發
生改變。
5. 數據訪問許可權的核對(data dict cache)。當語法、語義通過檢查之後,客戶端還不一定
能夠取得數據。伺服器進程還會檢查,你所連接的用戶是否有這個數據訪問的許可權。若你連接上伺服器
的用戶不具有數據訪問許可權的話,則客戶端就不能夠取得這些數據。有時候我們查詢數據的時候,辛辛苦
苦地把 SQL 語句寫好、編譯通過,但是,最後系統返回個 「沒有許可權訪問數據」的錯誤信息,讓我們氣
半死。這在前端應用軟體開發調試的過程中,可能會碰到。所以,要注意這個問題,資料庫伺服器進程先
檢查語法與語義,然後才會檢查訪問許可權。
6. 確定最佳執行計劃 ?。當語句與語法都沒有問題,許可權也匹配的話,伺服器進程還是不會直接對
資料庫文件進行查詢。伺服器進程會根據一定的規則,對這條語句進行優化。不過要注意,這個優化是有
限的。一般在應用軟體開發的過程中,需要對資料庫的 sql 語言進行優化,這個優化的作用要大大地大
於伺服器進程的自我優化。所以,一般在應用軟體開發的時候,資料庫的優化是少不了的。當伺服器進程
的優化器確定這條查詢語句的最佳執行計劃後,就會將這條 SQL 語句與執行計劃保存到數據高速緩存
(library cache)。如此的話,等以後還有這個查詢時,就會省略以上的語法、語義與許可權檢查的步驟,
而直接執行 SQL 語句,提高 SQL 語句處理效率。
第三步:語句執行
語句解析只是對 SQL 語句的語法進行解析,以確保伺服器能夠知道這條語句到底表達的是什麼意
思。等到語句解析完成之後,資料庫伺服器進程才會真正的執行這條 SQL 語句。這個語句執行也分兩
種情況。
一是若被選擇行所在的數據塊已經被讀取到數據緩沖區的話,則伺服器進程會直接把這個數據傳遞
給客戶端,而不是從資料庫文件中去查詢數據。
若數據不在緩沖區中,則伺服器進程將從資料庫文件中查詢相關數據,並把這些數據放入到數據緩沖
區中(buffer cache)。
第四步:提取數據
當語句執行完成之後,查詢到的數據還是在伺服器進程中,還沒有被傳送到客戶端的用戶進程。所以,
在伺服器端的進程中,有一個專門負責數據提取的一段代碼。他的作用就是把查詢到的數據結果返回給
用戶端進程,從而完成整個查詢動作。從這整個查詢處理過程中,我們在資料庫開發或者應用軟體開發過
程中,需要注意以下幾點:
一是要了解資料庫緩存跟應用軟體緩存是兩碼事情。資料庫緩存只有在資料庫伺服器端才存在,在
客戶端是不存在的。只有如此,才能夠保證資料庫緩存中的內容跟資料庫文件的內容一致。才能夠根據
相關的規則,防止數據臟讀、錯讀的發生。而應用軟體所涉及的數據緩存,由於跟資料庫緩存不是一碼事
情,所以,應用軟體的數據緩存雖然可以提高數據的查詢效率,但是,卻打破了數據一致性的要求,有時候
會發生臟讀、錯讀等情況的發生。所以,有時候,在應用軟體上有專門一個功能,用來在必要的時候清除
數據緩存。不過,這個數據緩存的清除,也只是清除本機上的數據緩存,或者說,只是清除這個應用程序
的數據緩存,而不會清除資料庫的數據緩存。
二是絕大部分 SQL 語句都是按照這個處理過程處理的。我們 DBA 或者基於 Oracle 資料庫的
開發人員了解這些語句的處理過程,對於我們進行涉及到 SQL 語句的開發與調試,是非常有幫助的。有
時候,掌握這些處理原則,可以減少我們排錯的時間。特別要注意,資料庫是把數據查詢許可權的審查放在
語法語義的後面進行檢查的。所以,有時會若光用資料庫的許可權控制原則,可能還不能滿足應用軟體許可權
控制的需要。此時,就需要應用軟體的前台設置,實現許可權管理的要求。而且,有時應用資料庫的許可權管
理,也有點顯得繁瑣,會增加伺服器處理的工作量。因此,對於記錄、欄位等的查詢許可權控制,大部分程
序涉及人員喜歡在應用程序中實現,而不是在資料庫上實現。
DBCC DROPCLEANBUFFERS
從緩沖池中刪除所有清除緩沖區。
DBCC FREEPROCCACHE
從過程緩存中刪除所有元素。
DBCC FREESYSTEMCACHE
從所有緩存中釋放所有未使用的緩存條目
SQL語句中的函數、關鍵字、排序等執行順序:
1. FROM 子句返回初始結果集。
2. WHERE 子句排除不滿足搜索條件的行。
3. GROUP BY 子句將選定的行收集到 GROUP BY 子句中各個唯一值的組中。
4. 選擇列表中指定的聚合函數可以計算各組的匯總值。
5. 此外,HAVING 子句排除不滿足搜索條件的行。
6. 計算所有的表達式;
7. 使用 order by 對結果集進行排序。
8. 查找你要搜索的欄位。
二、SQL語句執行完整過程:
1.用戶進程提交一個 sql 語句:
update temp set a=a*2,給伺服器進程。
2.伺服器進程從用戶進程把信息接收到後,在 PGA 中就要此進程分配所需內存,存儲相關的信息,如在會
話內存存儲相關的登錄信息等。
3.伺服器進程把這個 sql 語句的字元轉化為 ASCII 等效數字碼,接著這個 ASCII 碼被傳遞給一個
HASH 函數,並返回一個 hash 值,然後伺服器進程將到shared pool 中的 library cache 中去查找是否存在相
同的 hash 值,如果存在,伺服器進程將使用這條語句已高速緩存在 SHARED POOL 的library cache 中的已
分析過的版本來執行。
4.如果不存在,伺服器進程將在 CGA 中,配合 UGA 內容對 sql,進行語法分析,首先檢查語法的正確性,接
著對語句中涉及的表,索引,視圖等對象進行解析,並對照數據字典檢查這些對象的名稱以及相關結構,並根據
ORACLE 選用的優化模式以及數據字典中是否存在相應對象的統計數據和是否使用了存儲大綱來生成一個
執行計劃或從存儲大綱中選用一個執行計劃,然後再用數據字典核對此用戶對相應對象的執行許可權,最後生成
一個編譯代碼。
5.ORACLE 將這條 sql 語句的本身實際文本、HASH 值、編譯代碼、與此語名相關聯的任何統計數據
和該語句的執行計劃緩存在 SHARED POOL 的 library cache中。伺服器進程通過 SHARED POOL 鎖存
器(shared pool latch)來申請可以向哪些共享 PL/SQL 區中緩存這此內容,也就是說被SHARED POOL 鎖存
器鎖定的 PL/SQL 區中的塊不可被覆蓋,因為這些塊可能被其它進程所使用。
6.在 SQL 分析階段將用到 LIBRARY
CACHE,從數據字典中核對表、視圖等結構的時候,需要將數據
字典從磁碟讀入 LIBRARY
CACHE,因此,在讀入之前也要使用LIBRARY
CACHE 鎖存器(library cache
pin,library cache lock)來申請用於緩存數據字典。 到現在為止,這個 sql 語句已經被編譯成可執行的代碼了,
但還不知道要操作哪些數據,所以伺服器進程還要為這個 sql 准備預處理數據。
7.首先伺服器進程要判斷所需數據是否在 db buffer 存在,如果存在且可用,則直接獲取該數據,同時根據
LRU 演算法增加其訪問計數;如果 buffer 不存在所需數據,則要從數據文件上讀取首先伺服器進程將在表頭部
請求 TM 鎖(保證此事務執行過程其他用戶不能修改表的結構),如果成功加 TM 鎖,再請求一些行級鎖(TX
鎖),如果 TM、TX 鎖都成功加鎖,那麼才開始從數據文件讀數據,在讀數據之前,要先為讀取的文件准備好
buffer 空間。伺服器進程需要掃面 LRU list 尋找 free db buffer,掃描的過程中,伺服器進程會把發現的所有
已經被修改過的 db buffer 注冊到 dirty list 中, 這些 dirty buffer 會通過 dbwr 的觸發條件,隨後會被寫出到
數據文件,找到了足夠的空閑 buffer,就可以把請求的數據行所在的數據塊放入到 db buffer 的空閑區域或者
覆蓋已經被擠出 LRU list 的非臟數據塊緩沖區,並排列在 LRU list 的頭部,也就是在數據塊放入 DB
BUFFER 之前也是要先申請 db buffer 中的鎖存器,成功加鎖後,才能讀數據到 db buffer。
8.記日誌 現在數據已經被讀入到 db buffer 了,現在伺服器進程將該語句所影響的並被讀
入 db buffer 中的這些行數據的 rowid 及要更新的原值和新值及 scn 等信息從 PGA 逐條的寫入 redo log
buffer 中。在寫入 redo log buffer 之前也要事先請求 redo log buffer 的鎖存器,成功加鎖後才開始寫入,當
寫入達到 redo log buffer 大小的三分之一或寫入量達到 1M 或超過三秒後或發生檢查點時或者 dbwr 之前
發生,都會觸發 lgwr 進程把 redo log buffer 的數據寫入磁碟上的 redo file 文件中(這個時候會產生log file
sync 等待事件)
已經被寫入 redofile 的 redo log buffer 所持有的鎖存器會被釋放,並可被後來的寫入信息覆蓋,
redo log buffer是循環使用的。Redo file 也是循環使用的,當一個 redo file 寫滿後,lgwr 進程會自動切換到
下一 redo file(這個時候可能出現 log fileswitch(checkpoint complete)等待事件)。如果是歸檔模式,歸檔進
程還要將前一個寫滿的 redo file 文件的內容寫到歸檔日誌文件中(這個時候可能出現 log file
switch(archiving needed)。
9.為事務建立回滾段 在完成本事務所有相關的 redo log buffer 之後,伺服器進程開始改寫這個 db buffer
的塊頭部事務列表並寫入 scn,然後 包含這個塊的頭部事務列表及 scn 信息的數據副本放入回滾段中,將
這時回滾段中的信息稱為數據塊的「前映像「,這個」前映像「用於以後的回滾、恢復和一致性讀。(回滾段可以
存儲在專門的回滾表空間中,這個表空間由一個或多個物理文件組成,並專用於回滾表空間,回滾段也可在其它
表空間中的數據文件中開辟。
10.本事務修改數據塊 准備工作都已經做好了,現在可以改寫 db buffer 塊的數據內容了,並在塊的頭部寫
入回滾段的地址。
11.放入 dirty list 如果一個行數據多次 update 而未 commit,則在回滾段中將會有多個「前映像「,除了第
一個」前映像「含有 scn 信息外,其他每個「前映像「的頭部都有 scn 信息和「前前映像」回滾段地址。一個
update 只對應一個 scn,然後伺服器進程將在 dirty list 中建立一
條指向此 db buffer 塊的指針(方便 dbwr 進程可以找到 dirty list 的 db buffer 數據塊並寫入數據文件中)。
接著伺服器進程會從數據文件中繼續讀入第二個數據塊,重復前一數據塊的動作,數據塊的讀入、記日誌、建
立回滾段、修改數據塊、放入 dirty list。當 dirty queue 的長度達到閥值(一般是 25%),伺服器進程將通知
dbwr 把臟數據寫出,就是釋放 db buffer 上的鎖存器,騰出更多的 free db buffer。前面一直都是在說明
oracle 一次讀一個數據塊,其實 oracle 可以一次讀入多個數據塊(db_file_multiblock_read_count 來設置一
次讀入塊的個數)
說明:
在預處理的數據已經緩存在 db buffer 或剛剛被從數據文件讀入到 db buffer 中,就要根據 sql 語句
的類型來決定接下來如何操作。
1>如果是 select 語句,則要查看 db buffer 塊的頭部是否有事務,如果有事務,則從回滾段中讀取數據;如
果沒有事務,則比較 select 的 scn 和 db buffer 塊頭部的 scn,如果前者小於後者,仍然要從回滾段中讀取數據;
如果前者大於後者,說明這是一非臟緩存,可以直接讀取這個 db buffer 塊的中內容。
2>如果是 DML 操作,則即使在 db buffer 中找到一個沒有事務,而且 SCN 比自己小的非臟
緩存數據塊,伺服器進程仍然要到表的頭部對這條記錄申請加鎖,加鎖成功才能進行後續動作,如果不成功,則要
等待前面的進程解鎖後才能進行動作(這個時候阻塞是 tx 鎖阻塞)。
用戶 commit 或 rollback 到現在為止,數據已經在 db buffer 或數據文件中修改完
成,但是否要永久寫到數文件中,要由用戶來決定 commit(保存更改到數據文件) rollback 撤銷數據的更改)。
1.用戶執行 commit 命令
只有當 sql 語句所影響的所有行所在的最後一個塊被讀入 db buffer 並且重做信息被寫入 redo log
buffer(僅指日誌緩沖區,而不包括日誌文件)之後,用戶才可以發去 commit 命令,commit 觸發 lgwr 進程,但不
強制立即 dbwr來釋放所有相應 db buffer 塊的鎖(也就是no-force-at-commit,即提交不強制寫),也就是說有
可能雖然已經 commit 了,但在隨後的一段時間內 dbwr 還在寫這條 sql 語句所涉及的數據塊。表頭部的行鎖
並不在 commit 之後立即釋放,而是要等 dbwr 進程完成之後才釋放,這就可能會出現一個用戶請求另一用戶
已經 commit 的資源不成功的現象。
A .從 Commit 和 dbwr 進程結束之間的時間很短,如果恰巧在 commit 之後,dbwr 未結束之前斷電,因為
commit 之後的數據已經屬於數據文件的內容,但這部分文件沒有完全寫入到數據文件中。所以需要前滾。由
於 commit 已經觸發 lgwr,這些所有未來得及寫入數據文件的更改會在實例重啟後,由 smon 進程根據重做日
志文件來前滾,完成之前 commit 未完成的工作(即把更改寫入數據文件)。
B.如果未 commit 就斷電了,因為數據已經在 db buffer 更改了,沒有 commit,說明這部分數據不屬於數
據文件,由於 dbwr 之前觸發 lgwr 也就是只要數據更改,(肯定要先有 log) 所有 DBWR,在數據文件上的修改
都會被先一步記入重做日誌文件,實例重啟後,SMON 進程再根據重做日誌文件來回滾。
其實 smon 的前滾回滾是根據檢查點來完成的,當一個全部檢查點發生的時候,首先讓 LGWR 進程將
redo log buffer 中的所有緩沖(包含未提交的重做信息)寫入重做日誌文件,然後讓 dbwr 進程將 db buffer 已
提交的緩沖寫入數據文件(不強制寫未提交的)。然後更新控制文件和數據文件頭部的 SCN,表明當前資料庫
是一致的,在相鄰的兩個檢查點之間有很多事務,有提交和未提交的。
像前面的前滾回滾比較完整的說法是如下的說明:
A.發生檢查點之前斷電,並且當時有一個未提交的改變正在進行,實例重啟之後,SMON 進程將從上一個
檢查點開始核對這個檢查點之後記錄在重做日誌文件中已提交的和未提交改變,因為
dbwr 之前會觸發 lgwr,所以 dbwr 對數據文件的修改一定會被先記錄在重做日誌文件中。因此,斷電前被
DBWN 寫進數據文件的改變將通過重做日誌文件中的記錄進行還原,叫做回滾,
B. 如果斷電時有一個已提交,但 dbwr 動作還沒有完全完成的改變存在,因為已經提交,提交會觸發 lgwr
進程,所以不管 dbwr 動作是否已完成,該語句將要影響的行及其產生的結果一定已經記錄在重做日誌文件中
了,則實例重啟後,SMON 進程根據重做日誌文件進行前滾.
實例失敗後用於恢復的時間由兩個檢查點之間的間隔大小來決定,可以通個四個參數設置檢查點執行的頻
率:
Log_checkpoint_interval:
決定兩個檢查點之間寫入重做日誌文件的系統物理塊(redo blocks)
的大小,默認值是 0,無限制。
log_checkpoint_timeout:
兩 個 檢 查 點 之 間 的 時 間 長 度(秒)默 認 值 1800s。
fast_start_io_target:
決定了用於恢復時需要處理的塊的多少,默認值是 0,無限制。
fast_start_mttr_target:
直接決定了用於恢復的時間的長短,默認值是 0,無限制(SMON 進程執行的前滾
和回滾與用戶的回滾是不同的,SMON 是根據重做日誌文件進行前滾或回滾,而用戶的回滾一定是根據回滾段
的內容進行回滾的。
在這里要說一下回滾段存儲的數據,假如是 delete 操作,則回滾段將會記錄整個行的數據,假如是 update,
則回滾段只記錄被修改了的欄位的變化前的數據(前映像),也就是沒有被修改的欄位是不會被記錄的,假如是
insert,則回滾段只記錄插入記錄的 rowid。 這樣假如事務提交,那回滾段中簡單標記該事務已經提交;假如是
回退,則如果操作是 delete,回退的時候把回滾段中數據重新寫回數據塊,操作如果是 update,則把變化前數據
修改回去,操作如果是 insert,則根據記錄的 rowid 把該記錄刪除。
2.如果用戶 rollback。
則伺服器進程會根據數據文件塊和 DB BUFFER 中塊的頭部的事務列表和 SCN 以及回滾段地址找到
回滾段中相應的修改前的副本,並且用這些原值來還原當前數據文件中已修改但未提交的改變。如果有多個
「前映像」,伺服器進程會在一個「前映像」的頭部找到「前前映像」的回滾段地址,一直找到同一事務下的最早的
一個「前映像」為止。一旦發出了 COMMIT,用戶就不能rollback,這使得 COMMIT 後 DBWR 進程還沒有
全部完成的後續動作得到了保障。到現在為例一個事務已經結束了。
說明:
TM 鎖:
符合 lock 機制的,用於保護對象的定義不被修改。 TX 鎖:
這個鎖代表一個事務,是行
級鎖,用數據塊頭、數據記錄頭的一些欄位表示,也是符合 lock 機制,有 resource structure、lock
structure、enqueue 演算法。