Почему так долго получается пустой набор результатов в linqtosql? - PullRequest
0 голосов
/ 10 августа 2009

Я выполняю следующий запрос в своей базе данных, который генерирует запрос sql, который, как я знаю, возвращает 0 результатов, а при запуске в sql management studio возвращается менее секунды.

var query = (from item in db.Table
             where item.Field == FieldValue // Field is not the primary key but is indexed
             from other in item.Associated_Table
             select other.Table);
List<Table> result = query.ToList();

Associated_Table - это таблица соединения, которая связывает элементы в таблице с другими элементами в таблице. Результирующий запрос выглядит примерно так:

declare @p0 as int

SELECT 
   [t2].[ItemCategoryID], 
   [t2].[InventoryItemID], 
   [t2].[SiteID],
   [t2].[ItemDescription], 
   [t2].[AverageMonthlyUsage], 
   [t2].[ReorderLevel], 
   [t2].[ReorderQuantity], 
   [t2].[OtherItemDetails],
   [t2].[Price] AS [IntPrice], 
   [t2].[Ordinal], 
   [t2].[IsBase] AS [IntIsBase], 
   [t2].[Units], 
   [t2].[ProfitCenterID] AS [IntProfitCenterID], 
   [t2].[AccountID], 
   [t2].[PLU] AS [IntPLU], 
   [t2].[BarCode], 
   [t2].[DisplayName], 
   [t2].[ExtraServiceAmount] AS [IntExtraServiceAmount], 
   [t2].[IsSearchable], 
   [t2].[Terminated], 
   [t2].[PdxServiceKey], 
   [t2].[IsOpenPrice], 
   [t2].[ItemPromotionCategoryID]
FROM 
   [dbo].[Inventory.Item] AS [t0]
CROSS JOIN 
   [dbo].[Inventory.ItemExtraAssignment] AS [t1]
INNER JOIN 
   [dbo].[Inventory.Item] AS [t2] 
      ON [t2].[InventoryItemID] = [t1].[ExtraInventoryItemID]
WHERE 
   ([t0].[PLU] = @p0) AND 
   ([t1].[InventoryItemID] = [t0].[InventoryItemID])

В студии управления этот запрос выполняется менее чем за секунду и возвращает 0 результатов. Почему для выполнения 2 строк c #, выполняющих этот же запрос, требуется 2 секунды? Я понимаю, что LinqToSql проанализирует объекты, и это потребует некоторых накладных расходов, но, поскольку никакие объекты не возвращаются, не должно быть никакой работы.

Есть ли какая-то оптимизация, которую я пропускаю; или, может быть, какой-то параметр в самом dbml или SQL-сервере, который нужно изменить?

Ответы [ 3 ]

1 голос
/ 10 августа 2009

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

Попробуйте перестроить индексы для соответствующих таблиц или хотя бы обновить статистику.

[SSMS выдает pre-amble, который каждый раз вызывает перекомпиляцию]

1 голос
/ 10 августа 2009

Linq должен переводить дерево выражений во время выполнения. Обычно оно переводит дерево выражений как часть оценки запроса, но для многих запросов это можно сделать отдельно, используя CompiledQuery.

  //do this once
Func<CustomDataContext, int, List<Table>> queryFunc =
System.Data.Linq.CompiledQuery.Compile<CustomDataAccess, int, List<Table>>
( (dc, i) =>
  from item in dc.Table
  where item.Field == i
  from other in item.Associated_Table
  select other.Table).ToList()
);
   //time this
List<Table> result = queryFunc(db, FieldValue);
0 голосов
/ 10 августа 2009

Требуется ли еще 2 секунды для повторного выполнения запроса? LINQ to SQL может занять достаточно много времени, чтобы загрузить свои зависимости и выполнить различные биты инициализации в первый раз, но после этого быстро.

Кроме того, я предлагаю вам посмотреть журналы SQL Server и посмотреть, сколько времени запрос выполнялся в базе данных при запуске из LINQ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...