Apakah gabungan dioptimalkan ke klausa tempat saat runtime?


14

Ketika saya menulis permintaan seperti ini ...

select *
from table1 t1
join table2 t2
on t1.id = t2.id

Apakah pengoptimal SQL, tidak yakin apakah itu istilah yang benar, menerjemahkannya ke ...

select *
from table1 t1, table2 t2
where t1.id = t2.id

Pada dasarnya, apakah pernyataan Bergabung dalam SQL Server hanyalah cara yang lebih mudah untuk menulis sql? Atau apakah ini benar-benar digunakan pada saat run-time?

Sunting: Saya hampir selalu, dan hampir selalu, menggunakan sintaks Gabung. Saya hanya ingin tahu apa yang terjadi.


1
Bisakah Anda menguraikan "hampir"? Kapan Anda akan menggunakan sintaks gaya lama dan mengapa?
Aaron Bertrand

2
Satu sisi tepi di mana itu membuat perbedaan adalah jika Anda menambahkan (tidak berlaku) GROUP BY ALLdi
Martin Smith

@ MartinSmith apakah ada GROUP BY ALLyang sengaja digunakan? :-)
Aaron Bertrand

@ AaronBertrand - Saya ragu! Jangan pikir saya pernah melihat orang menggunakannya.
Martin Smith

Jawaban:


20

Itu runtuh ke hal yang sama secara internal. Yang pertama adalah yang harus selalu Anda tulis . Lebih penting lagi, mengapa itu penting? Mereka identik dalam hal rencana dan kinerja eksekusi (dengan asumsi Anda tidak mengacaukannya, yang lebih mudah dilakukan dengan sintaks gaya lama yang malas).

Inilah bukti menggunakan AdventureWorks bahwa tidak ada CROSS JOINdan filterterjadi.


Bergabung secara eksplisit:

masukkan deskripsi gambar di sini


Bergabung secara implisit:

masukkan deskripsi gambar di sini


Lihat, bu! Rencana identik, hasil identik, tidak ada sambungan silang atau filter yang terlihat di mana pun.

(Untuk kejelasan, peringatan pada SELECToperator dalam kedua kasus adalah konversi tersirat yang mempengaruhi kardinalitas, tidak ada hubungannya dengan sambungan dalam kedua kasus tersebut.)


20

Sebenarnya, ada perbedaan dalam input ke optimizer permintaan antara dua bentuk:

-- Input tree (ISO-89)
SELECT
    p.Name,
    Total = SUM(inv.Quantity)
FROM 
    Production.Product AS p,
    Production.ProductInventory AS inv
WHERE
    inv.ProductID = p.ProductID
GROUP BY
    p.Name
OPTION (RECOMPILE, QUERYTRACEON 8605, QUERYTRACEON 3604);

Pohon input ISO-89

-- Input tree (ISO-92)
SELECT
    p.Name,
    Total = SUM(inv.Quantity)
FROM Production.Product AS p
JOIN Production.ProductInventory AS inv ON
    inv.ProductID = p.ProductID
GROUP BY
    p.Name
OPTION (RECOMPILE, QUERYTRACEON 8605, QUERYTRACEON 3604);

Pohon input ISO-92

Seperti yang Anda lihat, ONpredikat klausa terikat erat dengan join menggunakan sintaksis modern. Dengan sintaks yang lebih lama, ada gabungan silang logis diikuti oleh pilih relasional (filter baris).

Pengoptimal kueri hampir selalu menciutkan pilihan relasional ke dalam gabungan selama optimisasi, yang berarti kedua formulir tersebut kemungkinan besar akan menghasilkan rencana kueri yang setara, tetapi tidak ada jaminan yang sebenarnya.


4

Untuk join dalam mereka dapat dipertukarkan, tetapi untuk Outer Joins mereka memiliki arti yang berbeda - ON cocok dan DI MANA adalah penyaringan sederhana. Jadi lebih baik untuk tetap berpadanan dengan sintaks GABUNG.


4

OK, saya penasaran jadi saya melakukan tes. Saya punya rencana eksekusi aktual untuk yang berikut.

select * 
from sys.database_principals prin, sys.database_permissions perm
WHERE prin.principal_id = perm.grantee_principal_id

dan

select * 
from sys.database_principals prin
JOIN sys.database_permissions perm
    ON prin.principal_id = perm.grantee_principal_id

Saya membandingkan mereka objek demi objek dan mereka identik. Jadi setidaknya untuk contoh yang sangat sederhana, mereka keluar untuk hal yang sama. Saya juga memeriksa statistik IO dan waktu dan mereka cukup dekat untuk menjadi hal yang sama.

Yang sedang berkata, Anda harus menggunakan JOINsintaksis karena lebih mudah dibaca dan Anda cenderung membuat kesalahan, terutama dalam pertanyaan yang rumit. Dan *=/ =*sintaks untuk OUTERbergabung telah dihapus sebagai SQL-Server 2005.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.