Когда вы захватываете запрос из SQL Profiler и запускаете его в SSMS, вы запускаете его как запрос sp_executesql? Я столкнулся с подобной проблемой при использовании NHibernate 2.1GA, и этот ответ относится к той версии, я еще не перешел на NH3. NH Profiler - отличный инструмент, но он услужливо извлекает SQL в форматированный запрос, который не соответствует фактическому запросу, отправленному на сервер.
Проблема в том, как NHibernate предоставляет строковые параметры в sp_executesql. Строковые параметры печатаются как nvarchar с длиной, равной длине значения. Например, этот запрос ограничивает два столбца: varchar (4) и varchar (20) соответственно:
exec sp_executesql N'SELECT this_.Column0, this_.Column1 FROM MySchema.MyTable this_ WHERE this_.Column0 = @p0 and this_.Column1 = @p1',N'@p0 nvarchar(4),@p1 nvarchar(7)',@p0='Val0',@p1='Value01'
План запроса для этого использовал сканирование индекса и занял 17 секунд. Изменение nvarchar на varchar привело к созданию плана, который использовал поиск по индексу и выполнялся в течение <2 секунд. Это было воспроизводимо в SSMS. </p>
Основной причиной было то, что NHibnerate по умолчанию использует DbType.String вместо DbType.AnsiString для столбцов varchar. Решением для меня было добавить соглашение Fluent NHibernate для изменения всех отображений строк на AnsiString, что заставило NHibernate создавать запросы, предоставляющие параметры в виде varchar.