Принудительная подсказка для индексации из структуры сущностей в 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 не предлагает необходимую вам функциональность, и я не думаю, что это так.