遇到同樣 SQL,參數化版本(@OrderDetailID nvarchar(50))極慢,直接寫死字面值('R1502003963580C001')卻秒回?根因通常是**參數類型與欄位定義不一致**,導致隱含轉換、索引失效、執行計劃無法複用。
-- 慢:參數化
declare @OrderDetailID nvarchar(50)
set @OrderDetailID='R1502003963580C001'
select * from BillDetail where OrderDetailID=@OrderDetailID
-- 快:字面值
select * from BillDetail where OrderDetailID='R1502003963580C001'
OrderDetailID 為 varchar,但參數宣告為 nvarchar。nvarchar 再比較,**導致索引掃描變為索引掃描/表掃描**,效能暴跌。nvarchar(50) vs nvarchar(40))會產生多個執行計劃,污染 Plan Cache。declare @OrderDetailID varchar(20) -- 與欄位定義完全一致
set @OrderDetailID='R1502003963580C001'
select * from BillDetail where OrderDetailID=@OrderDetailID
C# 端同步修正:
new SqlParameter("@name", SqlDbType.VarChar, 20) { Value = name };
declare @OrderDetailID varchar(20)
set @OrderDetailID='R1502003963580C001'
exec('select * from BillDetail where OrderDetailID=''' + @OrderDetailID + '''')
此法將參數「內插」為字面值,繞過參數嗅探與類型轉換,**但需防 SQL 注入**,僅建議內部可控場景使用。
SqlParameter 時**明確指定 SqlDbType 與 Size**。OPTION (RECOMPILE) 或 Plan Guide 干預。