Рекомендации по удалению нескольких подзапросов (которые содержат объединение) путем оптимизации запроса Linq To SQL - PullRequest
1 голос
/ 03 ноября 2008

Я работаю над добавлением глобализации в мой каталог продуктов, и я заставил его работать. Однако я чувствую, что базовый SQL-запрос работает не так хорошо, как мог бы, и мне может понадобиться несколько советов, как изменить мой запрос Linq To SQL, чтобы сделать его более эффективным.

Используемые таблицы

Product содержит уникальный идентификатор для каждого продукта. Этот столбец называется EntityID

TextTranslation содержит глобализированный текст. Столбцы в этой таблице: CultureID (строка), TextID (ссылка на текст), Value (фактически глобализированный текст).

Текст содержит отображение между глобализированным текстом и продуктом. Существует также столбец, который указывает, какой это тип текста (например, имя, описание и т. Д.)

TextType содержит определение (идентификатор, имя и описание) для типа текста.

var culturedTexts =
  from translation in ctx.TextTranslations
  join text in ctx.Texts on translation.TextId equals text.TextId
  where translation.CultureId == "en-EN"
  select new
  {
    text.EntityId,
    text.TextTypeId,
    translation.Value,
  };

var products =
  from p in ctx.Products
  let texts = culturedTexts.Where(i => i.EntityId == p.EntityId)
  select new Model.Product
  {
    Description = texts.Where(c => c.TextTypeId == (int)TextType.Description).SingleOrDefault().Value,
    Name = texts.Where(c => c.TextTypeId == (int)TextType.Name).SingleOrDefault().Value
  };

Когда это выполняется, я получаю запрос, который выглядит как

SELECT (
    SELECT [t1].[Value]
    FROM [Common].[TextTranslation] AS [t1]
    INNER JOIN [Common].[Text] AS [t2] ON [t1].[TextId] = [t2].[TextId]
    WHERE ([t2].[TextTypeId] = 2) AND ([t2].[EntityId] = [t0].[EntityId]) AND ([t1].[CultureId] = 'sv-SE')
    ) AS [Description], (
    SELECT [t3].[Value]
    FROM [Common].[TextTranslation] AS [t3]
    INNER JOIN [Common].[Text] AS [t4] ON [t3].[TextId] = [t4].[TextId]
    WHERE ([t4].[TextTypeId] = 1) AND ([t4].[EntityId] = [t0].[EntityId]) AND ([t3].[CultureId] = 'sv-SE')
    ) AS [Name]
FROM [Catalog].[Product] AS [t0]

Таким образом, каждый глобализированный текст (имя, описание) в запросе LINQ получает свой собственный подзапрос и связанное соединение. Можно ли немного упростить это и удалить каждый тип текста, получая свое собственное соединение и подзапрос?

1 Ответ

1 голос
/ 03 ноября 2008

Ну, учитывая, что они получают разные значения TextTypeId, как бы вы предпочли, чтобы TSQL выглядел? Если вы делаете одно JOIN, вам нужно будет добавить беспорядок SELECT CASE или аналогичный, чтобы различать тип «1» и тип «2».

Один из вариантов - просто вернуть все подходящие строки и выполнить окончательное проецирование в памяти на клиенте, но, честно говоря, я ожидаю, что оптимизатор SQL в любом случае облегчит работу с этим TSQL ... особенно если этот запрос достигает хорошего индекса охвата.

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