譯自:
我在我的應用程式中使用簡單的查詢/儲存過程訪問乙個很大的表。但執行了很長時間。在where子句中,我使用了有索引並且高選擇性(selective)並且沒有用函式包裹的字段。但是看起來就像沒有使用索引一樣,問題出在那裡?
出現這種微秒的問題原因可能是作為引數的資料型別與查詢中的資料型別不一致。在這種情況下,sqlserver將會要麼把where中的列,要麼把引數的資料型別隱式轉換為更高階或者更低階的資料型別。當作為被查詢列被轉換時**換競爭中的犧牲者),將引起掃瞄(scan)來滿足查詢請求。讓我們看看以下兩個例子,第乙個例子使用示例資料庫adventureworks,我們將通過乙個客戶的accountnumber在sales.customer表中查詢這個客戶。accountnumber這一列的資料型別是varchar(10)並且上面有乙個唯一索引。執行下面的查詢並且檢視執行計畫,可以看到結果如我們所願:
create proceduredbo.precedencetest
(@accountnumber varchar(10))as
begin
set nocount on
select *
from sales.customer
where accountnumber = @accountnumber
endgo
exec dbo.precedencetest'aw00030113'
go執行計畫如下:
接著讓我們在引數上做些小改動,把它改為nvarchar(10),然後重新執行語句:
alter procedure dbo.precedencetest
(
@accountnumber nvarchar(10)
)
as
begin
set nocount on
select *
from sales.customer
where accountnumber = @accountnumber
end
go
exec dbo.precedencetest 'aw00030113'
go執行計畫顯示,優化器選擇了掃瞄territoryid上的索引。
檢查filter操作,可以看到accountnumber列上被隱式轉換了型別來匹配傳入的引數。由於資料型別varchar比引數型別nvarchar級別更低,導致其所在的索引失效。
現在讓我們驗證一下,在較低階別的資料型別作為查詢引數下的情況。在這個例子中,person.person 表的lastname列是nvarchar型別,並且上面存在乙個可用的索引,儲存過程傳入的引數是varchar型別:
alter procedure dbo.precedencetest(
@lastname varchar(50)
)
as
begin
set nocount on
select *
from person.person
where lastname = @lastname
end
go
exec dbo.precedencetest 'tamburello'
go執行計畫顯示,優化器選擇使用了索引查詢:
點開index seek的詳細資訊,可以看到列lastname的資料型別因為傳入引數的原因而隱式轉換成更高階的nvarchar型別。
當索引列不再被轉換所影響時,優化器可以自由地選擇最優執行計畫。
不管你是在應用程式或者在儲存過程中定義查詢引數,確保查詢引數中的資料型別和查詢列的資料型別相吻合能避免索引掃瞄和其他轉換引起的問題。
user-defined data types (highest)
sql_variant
xml
datetimeoffset
datetime2
datetime
smalldatetime
date
time
float
real
decimal
money
smallmoney
bigint
int
smallint
tinyint
bit
ntext
text
image
timestamp
uniqueidentifier
nvarchar(includingnvarchar(max))
nchar
varchar(includin**archar(max))
char
varbinary(includin**arbinary(max))
binary(lowest)
SqlServer資料型別
資料型別 型別 描 述 bit 整型 bit資料型別是整型,其值只能是0 1或空值。這種資料型別用於儲存只有兩種可能值的資料,如yes 或no true 或fa lse on 或off int 整型 int資料型別可以儲存從 231 2147483648 到231 2147483 647 之間的整數...
SQL Server 資料型別
1.sql server的資料型別 資料類弄是資料的一種屬性,表示資料所表示資訊的型別。任何一種計算機語言都定義了自己的資料型別。當然,不同的程式語言都具有不同的特點,所定義的資料型別的各類和名稱都或多或少有些不同。sqlserver 提供了 25 種資料型別 binary n varbinary ...
sql server資料型別
資料型別 描述儲存 char n 固定長度的字串。最多 8,000 個字元。nvarchar n 可變長度的字串。最多 8,000 個字元。varchar max 可變長度的字串。最多 1,073,741,824 個字元。text 可變長度的字串。最多 2gb 字元資料。資料型別 描述儲存 ncha...