本文使用的是Sql server 2005
準備工作:
我需要一張User表,這張表有幾個欄位,還有一個自增長的數字id,表結構如下:
這是一張比現實應用中簡單的多的使用者表,UserID是自增長欄位。
開始執行一個最簡單的INSERT:
INSERT INTO [DB_BJ].[dbo].[User] ([UserName] ,[Email] ,[Signature] ,[CreateTime] ,[IP]) VALUES ('yukaizhao' ,'yukaizhao@abc.com' ,'My Blog is http://www.cnblogs.com/yukaizhao/' ,'2010-06-01' ,'127.0.0.1')
我們在sql server管理器中,選中工具列中的顯示執行計畫的表徵圖(),並執行語句:
其執行計畫如下所示:
查詢計劃顯示sql server執行的sql並非我們寫的原始sql,sql server先智能的將我們的sql語句轉換為一個參數話的sql,如下:
INSERT INTO [DB_BJ].[dbo].[User]([UserName],[Email],[Signature],[CreateTime],[IP]) values(@1,@2,@3,@4,@5)
Sql server做了這步轉換之後就可以讓使用不同參數的sql可以使用同一個經過先行編譯的sql語句。
我們從執行計畫的各個步驟看一下這個insert的執行過程,注意看sql server的執行計畫要從右往左看.
1. 常量掃描做的工作是根據使用者輸入的sql中的常量產生一個行
MSDN的原話如下:
"The Constant Scan operator introduces one or more constant rows into a query. A Compute Scalar operator is often used after a Constant Scan to add columns to a row produced by the Constant Scan operator"
上面的話是MSDN上的解釋,常量掃描會引入一個或者多個常量行到一個查詢中;通常情況下緊跟常量掃描的是計算標量運算子,計算標量運算子會為常量掃描運算子產生的行添加列。
2. 計算標量,在這一步產生了自增id的值,請看,這一步輸出了一個運算式Expr1003,為什麼這個輸出值是自增id,請看第4中的圖
3. 第二個計算標量,將原始sql中的常量值賦給5個變數
4. 叢集索引插入,執行插入操作,將資料加入到資料表中,請看:
圖中的第一個紅框是給UserName賦值的運算式,[DB_BJ].[dbo].[User].[UserName] = RaiseIfNull([Expr1004]) ,這個謂詞中的DB_BJ是我的測試資料庫名字,RaiseIfNull應該是sql server自動添加的函數,用來在參數值為NULL是拋出異常;但是這個函數是不允許使用者調用的。
第二個紅框是給UserID賦值的,這裡可以印證我們在第2步中的推斷。
5. 最後一步是Insert,這一步將輸入的sql語句的執行計畫儲存起來以便複用。
這隻是一個最簡單的INSERT語句的分析,下一篇我們繼續分析一個稍微複雜一點的INSERT。
相關隨筆:Sql server Insert執行的秘密(下) 帶外鍵的INSERT分析