Czy posiadanie " lub " w stanie połączenia wewnętrznego to zły pomysł?
Próbując poprawić szybkość niezwykle powolnego zapytania (kilka minut na dwóch tabelach z zaledwie ~50 000 wierszy każda, na SQL Server 2008, jeśli to ma znaczenie), zawęziłem problem do OR
w moim wewnętrznym połączeniu, jak w:
SELECT mt.ID, mt.ParentID, ot.MasterID
FROM dbo.MainTable AS mt
INNER JOIN dbo.OtherTable AS ot ON ot.ParentID = mt.ID
OR ot.ID = mt.ParentID
Zmieniłem to na (mam nadzieję) równoważną parę lewych łączników, pokazaną tutaj:
SELECT mt.ID, mt.ParentID,
CASE WHEN ot1.MasterID IS NOT NULL THEN
ot1.MasterID ELSE
ot2.MasterID END AS MasterID
FROM dbo.MainTable AS mt
LEFT JOIN dbo.OtherTable AS ot1 ON ot1.ParentID = mt.ID
LEFT JOIN dbo.OtherTable AS ot2 ON ot2.ID = mt.ParentID
WHERE ot1.MasterID IS NOT NULL OR ot2.MasterID IS NOT NULL
.. a zapytanie działa teraz w około sekundę!
Czy to ogólnie zły pomysł, aby umieścić OR
w stanie join? Or am I po prostu pechowo w układzie moich stołów?
3 answers
Ten rodzaj JOIN
nie jest optymalny dla HASH JOIN
lub MERGE JOIN
.
Można ją wyrazić jako konkatenację dwóch wyników:
SELECT *
FROM maintable m
JOIN othertable o
ON o.parentId = m.id
UNION
SELECT *
FROM maintable m
JOIN othertable o
ON o.id = m.parentId
, każdy z nich jest equijoinem, jednak optymalizator SQL Server
nie jest wystarczająco inteligentny, aby zobaczyć go w zapytaniu, które napisałeś (choć są logicznie równoważne).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-26 14:36:06
Używam poniższego kodu, aby uzyskać inny wynik z warunku To mi pomogło.
Select A.column, B.column
FROM TABLE1 A
INNER JOIN
TABLE2 B
ON A.Id = (case when (your condition) then b.Id else (something) END)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-21 18:21:07
Możesz użyć UNION ALL zamiast tego.
SELECT mt.ID, mt.ParentID, ot.MasterID
FROM dbo.MainTable AS mt
Union ALL
SELECT mt.ID, mt.ParentID, ot.MasterID
FROM dbo.OtherTable AS ot
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-21 10:22:47