Dalam mencoba meningkatkan kecepatan kueri yang sangat lambat (beberapa menit di dua tabel dengan masing-masing hanya ~ 50.000 baris, di SQL Server 2008 jika itu penting), saya mempersempit masalah ke OR
dalam gabungan batin saya, seperti di:
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
Saya mengubah ini menjadi (yang saya harap adalah) pasangan kiri yang setara, yang ditunjukkan di sini:
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
.. dan kueri sekarang berjalan sekitar satu detik!
Apakah umumnya merupakan ide yang buruk untuk memasukkan OR
kondisi gabungan? Atau apakah saya hanya tidak beruntung dalam tata letak tabel saya?
sql
sql-server
sql-server-2008
tsql
inner-join
ladenedge
sumber
sumber
Jawaban:
Jenis
JOIN
ini tidak dapat dioptimalkan untuk aHASH JOIN
atau aMERGE JOIN
.Ini dapat dinyatakan sebagai rangkaian dari dua kumpulan hasil:
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
, masing-masing menjadi equijoin, namun,
SQL Server
pengoptimal tidak cukup pintar untuk melihatnya dalam kueri yang Anda tulis (meskipun secara logis setara).sumber
ON w=x OR y=z
pola sepenuhnya?ON w=x OR y=z
? (Terima kasih atas kesabaran Anda!)SQL Server
memahami bahwa diperlukan penggabungan. Katakanlah, kueriSELECT * FROM othertable WHERE parentId = 1 OR id = 2
akan menggunakan penggabungan jika kedua bidang diindeks sehingga secara teoritis tidak ada yang akan mencegah melakukan hal yang sama dalam satu putaran. ApakahSQL Server
akan membangun rencana ini sebenarnya atau tidak, bergantung pada banyak faktor, tetapi saya belum pernah melihatnya dibangun dalam kehidupan nyata.Saya menggunakan kode berikut untuk mendapatkan hasil yang berbeda dari kondisi yang berhasil untuk saya.
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)
sumber
Anda dapat menggunakan UNION ALL sebagai gantinya.
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
sumber
UNION ALL
akan memberi Anda duplikat dibandingkanJOIN
denganOR
kondisi.union all
yang tidak benar seperti artikel yang Anda tautkan juga dijelaskan.