MySQL sorgularında, neden nerede yerine join kullanılsın?


109

Görünüşe göre iki veya daha fazla tabloyu birleştirmek gibi, ya birleştirme ya da nerede kullanabiliriz. Birinin diğerine göre avantajları nelerdir?


2
Kullanımınıza bağlı olarak, muhtemelen aynı sonuçları verir, ancak bir JOIN ile başka tür ilişkilendirmeler yapabilirsiniz.
zneak

Bu sorunuzu yanıtlıyor mu? INNER JOIN ON vs WHERE cümlesi
philipxy

Yanıtlar:


161

Birden fazla tabloyu içeren herhangi bir sorgu, "A" tablosundaki sonuçları "B" tablosuna bağlamak için bir tür ilişkilendirme gerektirir. Bunu yapmanın geleneksel (ANSI-89) yolu:

  1. FROM yan tümcesinde virgülle ayrılmış bir listede yer alan tabloları listeleyin
  2. Tablolar arasındaki ilişkiyi WHERE yan tümcesine yazın

    SELECT *
      FROM TABLE_A a,
           TABLE_B b
     WHERE a.id = b.id

ANSI-92 JOIN sözdizimi kullanılarak yeniden yazılan sorgu:

SELECT *
  FROM TABLE_A a
  JOIN TABLE_B b ON b.id = a.id

Performans Perspektifinden:


Desteklendiği yerlerde (Oracle 9i +, PostgreSQL 7.2+, MySQL 3.23+, SQL Server 2000+), her iki sözdizimini diğerine göre kullanmanın hiçbir performans avantajı yoktur. İyileştirici bunları aynı sorgu olarak görür. Ancak daha karmaşık sorgular ANSI-92 sözdiziminin kullanımından yararlanabilir:

  • JOIN sırasını kontrol etme yeteneği - tabloların taranma sırası
  • Katılmadan önce bir tabloya filtre kriterleri uygulayabilme

Bakım Perspektifinden:


ANSI-89 üzerinden ANSI-92 JOIN sözdizimini kullanmanın birçok nedeni vardır:

  • JOIN kriteri WHERE ifadesinden ayrı olduğu için daha okunaklı
  • JOIN kriterlerini kaçırma olasılığı daha düşüktür
  • INNER dışındaki JOIN türleri için tutarlı sözdizimi desteği, sorguların diğer veritabanlarında kullanımını kolaylaştırır
  • WHERE cümlesi yalnızca birleştirilen tabloların kartezyen ürününün filtrelenmesi olarak hizmet eder

Tasarım Perspektifinden:


ANSI-92 JOIN sözdizimi kalıptır, örüntü önleyici değildir:

  • Sorgunun amacı daha açıktır; uygulama tarafından kullanılan sütunlar açık
  • Mümkün olduğunda katı yazım kullanımına ilişkin modülerlik kuralını izler. Açık, neredeyse evrensel olarak daha iyidir.

Sonuç


Aşinalık ve / veya rahatlık kısa, ANSI-92 JOIN sözdizimi yerine ANSI-89 WHERE yan tümcesini kullanmaya devam etmenin herhangi bir faydası görmüyorum. Bazıları ANSI-92 sözdiziminin daha ayrıntılı olduğundan şikayet edebilir, ancak bu onu açık hale getirir. Ne kadar açık olursa, anlamak ve sürdürmek o kadar kolay olur.


14
"... Birden fazla tabloyu içeren herhangi bir sorgu, sonuçları 'A' tablosundan 'B' tablosuna bağlamak için bir tür ilişkilendirme gerektirir ... Aksi takdirde bir Kartezyen Ürün alırsınız ve muhtemelen bunu istemezsiniz (Kartezyalılar LOUSY ürünler yapıyorlar).
Scott Smith

8

Çoğu insan, JOIN sözdizimini neye neye katıldığı konusunda biraz daha net bulma eğilimindedir. Ayrıca standart olma avantajına sahiptir.

Kişisel olarak, WHEREs'de "büyüdüm", ancak JOIN sözdizimini ne kadar çok kullanırsam, bunun daha net olduğunu görmeye başladım.


1
@nawfal Anlıyorum - eski tarz sözdiziminde yetiştirildim ama yenisine alıştıktan sonra faydalar netleşti, örneğin yanlışlıkla çapraz birleştirme yapmak daha zor, daha açık, bir birleşmenin ne olduğunu ve ne olduğunu görmek daha kolay bir filtre vs ... Bağlandım.
Temel

8

Where sözdizimini (örtük birleştirme olarak bilinen diğer akıllıca) kullanmanın sorunları şunlardır:

İlk olarak, birleştirme koşulları tablo adlarının hemen yanında olmadığından, yanlışlıkla çapraz birleşimler elde etmek çok kolaydır. Birleştirilmiş 6 tablonuz varsa, where cümlesinde birini gözden kaçırmak kolaydır. Farklı anahtar kelimeyi kullanarak bunun çok sık düzeltildiğini göreceksiniz. Bu, veritabanı için büyük bir performans darbesi. Sözdizimi denetiminde başarısız olacağından, açık birleştirme sözdizimini kullanarak yanlışlıkla bir çapraz birleşim elde edemezsiniz.

Bazı veritabanlarında eski sözdiziminde sağ ve sol birleşimler sorunludur (SQl sunucusunda doğru sonuçları alacağınız garanti edilmez). Ayrıca bildiğim SQL Server'da kullanımdan kaldırıldılar.

Çapraz birleştirme kullanmayı düşünüyorsanız, bu eski sözdiziminden anlaşılmıyor. Mevcut ANSII standardını kullanarak açıktır.

Bakımcı için, örtük sözdizimini kullanarak hangi alanların birleşimin parçası olduğunu ve hatta hangi tabloların hangi sırayla birleştiğini görmek çok daha zordur. Bu, sorguları gözden geçirmenin daha fazla zaman alabileceği anlamına gelir. Açık birleştirme sözdizimi ile kendilerini rahat hissetmek için zaman ayırdıklarında eski yola geri dönen çok az insan tanıyorum.

Ayrıca, bu örtük birleştirmeleri kullanan bazı kişilerin aslında birleştirmelerin nasıl çalıştığını anlamadıklarını ve bu nedenle sorgularında yanlış sonuçlar aldıklarını fark ettim.

Açıkçası, 18 yıl önce daha iyi bir yöntemle değiştirilen başka herhangi bir kod kullanır mıydınız?


6

Açık birleşimler amacı iletir ve filtrelemeyi yapmak için where cümlesini bırakır. Daha temiz ve standarttır ve sol dış veya sağ dış gibi sadece nerede yapılması daha zor şeyler yapabilirsiniz.


3

İki tabloyu birleştirmek için WHERE kullanamazsınız. Yine de yapabileceğiniz şey yazmaktır:

SELECT * FROM A, B
WHERE ...

Buradaki virgül, yazmakla eşdeğerdir:

SELECT *
FROM A
CROSS JOIN B
WHERE ...

Bunu yazar mısın? Hayır - çünkü demek istediğin bu değil. Çapraz birleşme istemiyorsunuz, bir INNER JOIN istiyorsunuz. Ama virgül yazdığınızda, CROSS JOIN diyorsunuz ve bu kafa karıştırıcı.


0

Aslında çoğu zaman hem "NEREDE" hem de "KATILIN" gerekir.

"JOIN", ortak bir sütunun değerlerine bağlı olarak iki tablodan veri almak için kullanılır. Daha sonra bu sonucu daha fazla filtrelemek isterseniz, WHERE yan tümcesini kullanın.

Örneğin, "LEFT JOIN" soldaki tablodan TÜM satırları artı sağ tablodan eşleşen satırları alır. Ancak bu, belirli bir değere veya JOIN'in parçası olmayan diğer sütunlara ilişkin kayıtları filtrelemez. Bu nedenle, bu sonucu daha fazla filtrelemek istiyorsanız, WHERE yan tümcesinde ekstra filtreleri belirtin.

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.