Bir JOIN veya IN kullanmak bana doğru sonuçları verecek bir durum var ... Hangisi genellikle daha iyi performans ve neden? Hangi veritabanı sunucusunu çalıştırdığınıza ne kadar bağlıdır? (FYI MSSQL kullanıyorum)
Bir JOIN veya IN kullanmak bana doğru sonuçları verecek bir durum var ... Hangisi genellikle daha iyi performans ve neden? Hangi veritabanı sunucusunu çalıştırdığınıza ne kadar bağlıdır? (FYI MSSQL kullanıyorum)
Yanıtlar:
Genel olarak konuşursak IN
ve JOIN
farklı sonuçlar verebilecek farklı sorgulardır.
SELECT a.*
FROM a
JOIN b
ON a.col = b.col
ile aynı değil
SELECT a.*
FROM a
WHERE col IN
(
SELECT col
FROM b
)
, b.col
benzersiz olmadığı sürece .
Ancak, bu ilk sorgunun eş anlamlısıdır:
SELECT a.*
FROM a
JOIN (
SELECT DISTINCT col
FROM b
)
ON b.col = a.col
Birleştirme sütunu UNIQUE
işaretlenmiş ve bu şekilde işaretlenmişse, her iki sorgu da aynı planı verir SQL Server
.
Değilse, o zaman IN
daha hızlı olduğu JOIN
üzerinde DISTINCT
.
Performans ayrıntıları için blogumdaki bu makaleye bakın:
IN
ima eder DISTINCT
. SQL Server
fark edebilecek kadar akıllıdır ve her iki sorgu için de aynı planlar oluşturur. Yine de, başkalarının nasıl RDBMS
davranacağından emin değilim .
Komik, bahsettiğiniz gibi, bu konuda bir blog yazısı yaptım.
Bkz SQL Server vs MySQL vs Oracle: Toplama vs Katıldı
Kısa cevap: test etmeniz gerekiyor ve bireysel veritabanları çok farklı.
Söylemek oldukça zor - hangisinin daha iyi çalıştığını gerçekten öğrenmek için, yürütme sürelerini gerçekten profillemeniz gerekir.
Genel bir kural olarak, yabancı anahtar sütunlarınızda endeksleriniz varsa ve yalnızca (veya çoğunlukla) INNER JOIN koşullarını kullanıyorsanız, JOIN biraz daha hızlı olacaktır.
Ancak, OUTER JOIN kullanmaya başlar başlamaz veya yabancı anahtar dizinleri yoksa, IN daha hızlı olabilir.
üzüm posası
Mantıksal farklar üzerine ilginç bir yazı: SQL Server: JOIN vs IN vs EXISTS - mantıksal fark
İlişkilerin ve indekslerin korunduğunu varsayarak bir Join'ın genel olarak daha iyi performans göstereceğinden eminim (bu işlemle diğerlerine göre daha fazla çaba harcanır). Kavramsal olarak düşünürseniz, 2 sorgu ve 1 sorgu arasındaki fark.
Sorgu Çözümleyicisi'ne bağlamanız ve denemeniz ve farkı görmeniz gerekir. Ayrıca Sorgu Yürütme Planına bakın ve adımları en aza indirmeye çalışın.
Bu Konu oldukça eski ama yine de sık sık bahsediliyor. Benim kişisel zevkime göre, bu biraz eksik, çünkü veritabanından EXISTS anahtar kelime ile sormak için daha sık daha hızlı buldum başka bir yolu var.
Dolayısıyla, yalnızca tablo a'daki değerlerle ilgileniyorsanız bu sorguyu kullanabilirsiniz:
SELECT a.*
FROM a
WHERE EXISTS (
SELECT *
FROM b
WHERE b.col = a.col
)
Col indekslenmezse fark çok büyük olabilir, çünkü db b'de col'da aynı değere sahip tüm kayıtları bulmak zorunda değildir, sadece ilkini bulmak zorundadır. B.col dizininde bir dizin yoksa ve ba tablo taramasında çok fazla kayıt olması bunun sonucu olabilir. IN veya JOIN ile bu tam tablo taraması, EXISTS ile bu sadece kısmi tablo taraması olacaktır (ilk eşleşen kayıt bulunana kadar).
Eğer b'de aynı col değerine sahip bir sürü kayıt varsa, sadece durumunuzun tatmin olduğunu bulmak için tüm bu kayıtları geçici bir alana okumak için çok fazla bellek harcarsınız. Var olduğundan bu genellikle önlenebilir.
Bir dizin olsa bile sık sık INISTS sonra IN daha hızlı bulduk. Veritabanı sistemine (optimizer), verilere ve son olarak en az kullanılan indeks türüne bağlıdır.
Her veritabanının uygulanması ancak muhtemelen ortak sorunların aşağı yukarı aynı şekilde çözüldüğünü tahmin edebilirsiniz. MSSQL kullanıyorsanız oluşturulan yürütme planına bir göz atın. Profil oluşturucu ve yürütme planlarını açarak bunu yapabilirsiniz. Bu, komutu çalıştırdığınızda size bir metin sürümü verecektir.
Hangi MSSQL sürümünü kullandığınızdan emin değilim ama sorgu çözümleyicide SQL Server 2000'de grafiksel bir sürüm alabilirsiniz. Bu işlevin SQL Server Studio Manager'ın sonraki sürümlerinde bazı yerlerde gizlendiğinden eminim.
Exeuction planına bir göz atın. Tablonuz küçük olmadığı sürece tablo taramalarından mümkün olduğunca kaçının; bu durumda tablo taraması bir dizin kullanmaktan daha hızlıdır. Her farklı senaryonun ürettiği farklı birleştirme işlemlerini okuyun.
Optimize edici, normal sorgular için her iki şekilde de aynı sonucu verecek kadar akıllı olmalıdır. İcra planını kontrol edin ve size aynı şeyi vermelidirler. Eğer yapmazlarsa, normalde JOIN'in daha hızlı olduğunu düşünürdüm. Tüm sistemler farklı olsa da, emin olmak için sisteminizdeki kodu profillemelisiniz.