SQL JOIN vs IN performansı?


164

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)


:) Aslında bir süre önce benzer bir şeyi araştırdığımda kullandığım farklı bir makale arıyordum ve yanlışlıkla
bununla karşılaştım

Olası dupe için üzgünüm ... ararken bu soruyu bulamadık
Polaris878

Yanıtlar:


197

Genel olarak konuşursak INve JOINfarklı 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.colbenzersiz 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 UNIQUEişaretlenmiş ve bu şekilde işaretlenmişse, her iki sorgu da aynı planı verir SQL Server.

Değilse, o zaman INdaha hızlı olduğu JOINüzerinde DISTINCT.

Performans ayrıntıları için blogumdaki bu makaleye bakın:


Evet, birleştirme sütunu benzersizse aynı şekilde yürütecekleri mantıklıdır (ki bu benim durumumdadır)
Polaris878

1
Benzer bir notta, IN (SELECT DISTINCT ...) veya sadece IN (SELECT ...) kullanmalı mıyım?
moo

8
@ orlandu63: INima eder DISTINCT. SQL Serverfark 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 RDBMSdavranacağından emin değilim .
Quassnoi

>> IN ve JOIN, farklı sonuçlar verebilecek farklı sorgulardır. B.col benzersiz olmasa bile, bu durumda neden farklı sonuç üreteceğini açıklayabilir misiniz?
Abhijeet

1
explainextended.com/2009/06/16/in-vs-join-vs-exists Gerçekten bana yardım ediyor .. Teşekkür ederim ..
Abbas Galiyakotwala


6

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ı


Ben de bunu düşünüyordum ... çünkü JOIN daha yaygın bir durum ve daha da optimize edilecek gibi görünüyor
Polaris878

4

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.


4

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.


3
MSSql'de var olan gerçek, bir IN'den daha iyi görünmemektedir. Daha fazla bilgi için: explainextended.com/2009/06/16/in-vs-join-vs-exists Burada şunu okuyabilirsiniz: "Birçoğu EXISTS'in IN'den daha verimli olduğunu düşünür, çünkü EXISTS yalnızca bir satır döndürür. Yukarıdaki örneklerden de görebileceğimiz gibi, EXISTS ve IN tam olarak aynı planları üretir, çünkü EXISTS IN'den daha esnektir. IN her zaman EXISTS olarak yeniden yazılabilir (equijoin ile basit bir WHERE koşulu kullanarak ), ancak tam tersi değil. "
Micaël Félix

3

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.


1

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.


5
Yapmak gerekir? Olabilir. Yapar? Hayýr. Yazýma bak.
cletus
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.