Я пытаюсь переписать процедуру SQL в Linq, все прошло хорошо и отлично работает, пока оно работает маленький набор данных. Я никак не мог найти ответ на это. Вещь есть, у меня есть 3 соединения в запросе, 2 - left joins
, а 1 - inner join
, все они соединяются друг с другом/как дерево. Ниже вы можете увидеть SQL процедуру:Linq-to-SQL левое соединение слева join/несколько левых объединений в одном выражении Linq-to-SQL
SELECT ...
FROM sprawa s (NOLOCK)
LEFT JOIN strona st (NOLOCK) on s.ident = st.id_sprawy
INNER JOIN stan_szczegoly ss (NOLOCK) on s.kod_stanu = ss.kod_stanu
LEFT JOIN broni b (NOLOCK) on b.id_strony = st.ident
То, что я хотел бы спросить у вас есть способ, чтобы перевести это Linq. Теперь у меня есть это:
var queryOne = from s in db.sprawa
join st in db.strona on s.ident equals st.id_sprawy into tmp1
from st2 in tmp1.DefaultIfEmpty()
join ss in db.stan_szczegoly on s.kod_stanu equals ss.kod_stanu
join b in db.broni on st2.ident equals b.id_strony into tmp2
from b2 in tmp2.DefaultIfEmpty()
select new { };
Кажется хорошо, но при проверке с SQL Profiler, запрос, который отправляется в базу данных выглядит следующим образом:
SELECT ... FROM [dbo].[sprawa] AS [Extent1]
LEFT OUTER JOIN [dbo].[strona] AS [Extent2]
ON [Extent1].[ident] = [Extent2].[id_sprawy]
INNER JOIN [dbo].[stan_szczegoly] AS [Extent3]
ON [Extent1].[kod_stanu] = [Extent3].[kod_stanu]
INNER JOIN [dbo].[broni] AS [Extent4]
ON ([Extent2].[ident] = [Extent4].[id_strony]) OR
(([Extent2].[ident] IS NULL) AND ([Extent4].[id_strony] IS NULL))
Как вы можете видеть оба запроса SQL являются немного по-другому , Эффект один и тот же, но последний работает несравненно медленнее (менее секунды до более 30 минут). Там также есть union
, но это не должно быть проблемой. Если меня попросят, я вложу код для него.
Буду благодарен за любые советы, как улучшить производительность моего заявления Linq или как написать его таким образом, чтобы он был правильно переведен.
Если zakreslenie - это переменная, вы можете разбить свой оператор в двух разных выражениях с помощью if (zakreslenie == - 1), затем {} else {} '. Операторы OR имеют тенденцию быть плохой для производительности, поэтому это может помочь. И если вы действительно не можете превратить сложный оператор linq в хорошо выполняющийся запрос, возможно, стоит подумать о вызове хранимой процедуры? – Sam
Плохо хранимая процедура тоже не работает. Кроме того, как я уже говорил, проблема связана с объединениями, все остальное работает отлично (переделано с помощью переведенного sql-запроса) – Rufix
Если вы не можете сделать быстрый SQL-запрос для выполнения того, что хотите, вы не сможете быстро выполнить оператор linq или. Оптимизация slq-запроса для скорости намного проще, чем оптимизация оператора linq, хотя, поскольку с помощью sql вы можете получить план объяснения, чтобы выяснить, что замедляет его. Это может быть OR в вашем запросе, который вызывает снижение вашей скорости, но это может быть и отсутствие правильной индексации. – Sam