Parameter參數中的DBType重要性

在加入DBCommand的Parameters,有沒有想過DBType這個問題,除了在使用Command.Prepare時,一定要指定,那麼其它時候是否要指定,而AddWithValue是否真的那麼[自動]的幫我們加上正確的型別?如果用錯DBType,那又有什麼差異?

在加入DBCommand的Parameters,有沒有想過DBType這個問題,除了在使用Command.Prepare時,一定要指定,那麼其它時候是否要指定,而AddWithValue是否真的那麼[自動]的幫我們加上正確的型別?如果用錯DBType,那又有什麼差異?

首先來看一下大多人認為它會自動幫我們辨別資料型別的AddWithValue().

建立一個簡單的Table.並在裡面新增1萬筆資料.

Name

Type

ID

Int

UserNo

Nvarchar(50)

執行一個簡單的查詢Script,重覆執行1000次,看它會執行多久,並透過Profiler看它的參數定義.

select * from testTable where UserNo=@UserNo

執行耗時 : 1.7696947秒

Profiler : exec sp_executesql N'select * from testTable where UserNo=@UserNo',N'@UserNo nvarchar(1)',@UserNo=N'0'

看來參數是設為nvarchar,它的型別與資料庫的一樣.

 

接下來把資料庫的UserNo型別從nvarchar改為varchar,再執行同樣的測試.

執行耗時 : 3.1780141秒

Profiler : exec sp_executesql N'select * from testTable where UserNo=@UserNo',N'@UserNo nvarchar(1)',@UserNo=N'0'

看到的參數定義仍是nvarchar,並沒有隨著資料庫欄位型別變更而改變,所以文字部份,它就是預設為nvarchar的型態.

 

從這邊還可以發現一件事,就是參數型別指定錯誤,還會影響到它的效能問題,同樣的Script,只是型別不同,就慢了1.X秒.

 

那麼錯誤的型別,是否會影響到使用Index的部份?在這個testTable的ID加上Index,來試看看如果參數是不同型別,是否會影響到Index使用的問題.

sql2005

看了一下它的執行計畫,上圖是正確的型別,下圖是錯誤型別,但它還是都能使用Index.

 

但說真的,這樣的結果我仍無法放心,主要是最近在Oracle 9i也同樣遇到型別問題,因為型別用錯了,剛開始慢的還好,不是很明顯,但一執行久了,整個IO的Read大幅上升,一個簡單的Script只帶回1筆資料,Table也有Index,卻還是要等個2X秒才回傳,而且慢的Script不是每一個都會,只有特定某幾個,後來想到AddWithValue在string的部份並不是依DB的Schema去套,還是有它預設的型別,後來加上正確的DBType就正常了,現在被蛇咬到一次,之後都會安份的加上正確的DBType了.

 

*以上的測試DB是SQL 2005 Standard SP3.