Принудительная подсказка для индексации из структуры сущностей в SQL Server

Я звоню SQL Server 10 из Entity Framework в C# и хочу получить подсказку запроса в запросе. База данных имеет индексы, которые обычно работают из SQL, запускаемого в Management Studio, но при вызове команды из C# с использованием Entity Framework в Visual Studio планировщик запросов выбирает полное сканирование, когда индекс уже существует.

Я создаю динамические предикаты для запроса данных в следующей форме:

data.attributeText = data.vegaDB.attributeText.AsExpandable().Where(parentPredicate.Compile()).ToList();

где parentPredicate динамически генерируемый эквивалент:

(parentID = p1) AND (attributeName = 'name OR ... ')          

Из которого план запроса SQL Server генерирует:

SELECT 
[Extent1].[attributeID] AS [attributeID],  
[Extent1].[parentID] AS [parentID],  
[Extent1].[typeID] AS [typeID],  
[Extent1].[attributeName] AS [attributeName],  
[Extent1].[attributeData] AS [attributeData]  
FROM [dbo].[attributeText] AS [Extent1]

Так что замена [Extent1] с указателем [IX_parentID], который использует прямой вызов sql, с помощью какой-нибудь дополнительной команды, которая делает подсказку запроса в начальном вызове C#, может показаться решением. Я осмотрелся вокруг, но безуспешно. Есть идеи, как сформулировать вопрос?

Как вы думаете, это правильное решение?

2 ответа

Попробуйте обновить статистику для связанных таблиц в вашей базе данных, если статистика устарела, и неоптимальные планы запросов, вероятно, будут использоваться для всех запросов.

Запустите трассировку SQL, чтобы узнать, какой SQL-запрос фактически генерируется для этого оператора.

Ваш предикат или эквивалент в действительности отображается в запросе с точки зрения SQL Server?

Если он появляется, вам нужно выполнить этот запрос с помощью мастера настройки индекса или подобного.

Если нет, то это ваша проблема - это будет означать, что Entity Framework загружает всю таблицу в память и применяет сам предикат.

Обновлено Я почти уверен, что это именно то, что происходит: AsExpandable () не может преобразовать ваш предикат в SQL, поэтому он генерирует код для чтения всей таблицы, а затем применяет предикат к возвращаемым данным.

Решение состоит в том, чтобы прекратить использование AsExpandable и использовать вместо этого AsQueryable. Единственная причина использовать AsExpandable - это то, что AsQueryable не предлагает необходимую вам функциональность, и я не думаю, что это так.

Другие вопросы по тегам