2011-03-16 56 views
0

我正在爲我的應用程序使用SubSonic SimpleRepository模板。我在VS2010中創建了一個指向SQL 2000數據庫的ASP .NET WebForms項目。SubSonic - 生成SQL使用nvarchar而不是varchar,這會導致索引掃描而不是查找

我有一個問題,其中SubSonic總是在參數化查詢中使用nvarchar而不是varchar。這會導致SQL執行索引掃描而不是索引搜索。我從Profiler中獲取了SQL並將其更改爲使參數varchar類似於表的字段,並且執行得非常快(< 1秒與8秒)。

亞音速查詢從探查

exec sp_executesql N'SELECT [t0].[ADDRESS_L1], [t0].[ADDRESS_L2], [t0].[ADDRESS_L3], [t0].[CITY], [t0].[COUNTRY] FROM [aveadmin].[SAPADD] AS t0 WHERE (([t0].[SITE_ID] = @p0) AND ((([t0].[ADDRESS_TYPE] = @p1) AND 1 <> 0) OR (([t0].[ADDRESS_TYPE] = @p2) AND 0 <> 0)))', N'@p0 nvarchar(16),@p1 nvarchar(2),@p2 nvarchar(2)', @p0 = N'BCF8A0A27E543EE1', @p1 = N'00', @p2 = N'03' 

手動修改的查詢

exec sp_executesql N'SELECT [t0].[ADDRESS_L1], [t0].[ADDRESS_L2], [t0].[ADDRESS_L3], [t0].[CITY], [t0].[COUNTRY] FROM [aveadmin].[SAPADD] AS t0 WHERE (([t0].[SITE_ID] = @p0) AND ((([t0].[ADDRESS_TYPE] = @p1) AND 1 <> 0) OR (([t0].[ADDRESS_TYPE] = @p2) AND 0 <> 0)))', N'@p0 varchar(16),@p1 varchar(2),@p2 varchar(2)', @p0 = N'BCF8A0A27E543EE1', @p1 = N'00', @p2 = N'03' 

SITE_ID的和ADDRESS_TYPEvarchars。有沒有辦法強制查詢使用varchar而不是nvarchar

回答

2

有沒有辦法強制查詢到 使用varchar而不是nvarchar?

您必須修改SubSonic的源代碼才能更改此行爲。

+0

好吧,我已經下載了源代碼並將開始挖掘。任何想法爲什麼他們總是會使用nvarchar參數時,該字段是一個varchar? – jamorgan 2011-03-17 15:52:01

+0

這可能是硬編碼的地方。這是一個相當簡單的庫,它可能將它用於任何char字段,並且它沒有真正經歷過某種可能的詳細優化,除了一個更大的更成熟的庫(如NHibernate或EF),並非它們是完美的)。 – 2011-03-17 16:47:35

0

[上一頁答案是正確的 - 進一步細節如下。]

使用爲nvarchar是硬編碼在一個叫GetNativeType()在Sql2005Schema.cs功能。很容易修補和重建。嘿,這是OSS!這是源代碼的用途!

這是代碼。

  case DbType.AnsiString: 
      case DbType.AnsiStringFixedLength: 
      case DbType.String: 
      case DbType.StringFixedLength: 
       return "nvarchar"; 

在理論上,所產生的代碼(參見SQLServer.ttinclude)實際上做產生DbType.AnsiString和DbType.String作爲單獨的類型。應該可以將switch語句分開,併爲其中一個生成「varchar」,爲另一個生成「nvarchar」。也許作者認爲這不重要。我建議你試一試(但它可能會打破單元測試)。

相關問題