SubSonic - Генерация SQL использует nvarchar вместо varchar, который вызывает сканирование индекса вместо поиска - PullRequest
0 голосов
/ 16 марта 2011

Я использую шаблон SubSonic SimpleRepository для своего приложения.Я создал проект ASP .NET WebForms в VS2010, указывающий на базу данных SQL 2000.

У меня возникла проблема, когда SubSonic всегда использует nvarchar в параметризованных запросах вместо varchar.Это заставляет SQL выполнять сканирование индекса вместо поиска индекса.Я взял SQL из Profiler и изменил его, чтобы сделать параметры varchar похожими на поля таблицы, и он выполняется очень быстро (<1 секунда против 8 секунд). </p>

SubSonic Query from Profiler

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_TYPE varchars.Есть ли способ заставить запрос использовать varchar вместо nvarchar?

Ответы [ 2 ]

2 голосов
/ 16 марта 2011

Есть ли способ заставить запрос использовать varchar вместо nvarchar?

Вам придется изменить исходный код SubSonic, чтобы изменить это поведение.

0 голосов
/ 14 января 2012

[Предыдущий ответ правильный - подробности следуют.]

Использование 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» для другого. Может быть, автор думал, что это не имеет значения. Я предлагаю вам попробовать (но это может нарушить юнит-тесты).

...