INNER JOIN vs kinerja LEFT JOIN di SQL Server

259

Saya telah membuat perintah SQL yang menggunakan INNER JOIN pada 9 tabel, toh perintah ini membutuhkan waktu yang sangat lama (lebih dari lima menit). Jadi rakyat saya menyarankan saya untuk mengubah INNER JOIN menjadi LEFT JOIN karena kinerja LEFT JOIN lebih baik, terlepas dari apa yang saya ketahui. Setelah saya mengubahnya, kecepatan kueri membaik secara signifikan.

Saya ingin tahu mengapa LEFT JOIN lebih cepat daripada INNER JOIN?

Perintah SQL saya terlihat seperti di bawah ini: SELECT * FROM A INNER JOIN B ON ... INNER JOIN C ON ... INNER JOIN Ddan seterusnya

Pembaruan: Ini adalah ringkasan skema saya.

FROM sidisaleshdrmly a -- NOT HAVE PK AND FK
    INNER JOIN sidisalesdetmly b -- THIS TABLE ALSO HAVE NO PK AND FK
        ON a.CompanyCd = b.CompanyCd 
           AND a.SPRNo = b.SPRNo 
           AND a.SuffixNo = b.SuffixNo 
           AND a.dnno = b.dnno
    INNER JOIN exFSlipDet h -- PK = CompanyCd, FSlipNo, FSlipSuffix, FSlipLine
        ON a.CompanyCd = h.CompanyCd
           AND a.sprno = h.AcctSPRNo
    INNER JOIN exFSlipHdr c -- PK = CompanyCd, FSlipNo, FSlipSuffix
        ON c.CompanyCd = h.CompanyCd
           AND c.FSlipNo = h.FSlipNo 
           AND c.FSlipSuffix = h.FSlipSuffix 
    INNER JOIN coMappingExpParty d -- NO PK AND FK
        ON c.CompanyCd = d.CompanyCd
           AND c.CountryCd = d.CountryCd 
    INNER JOIN coProduct e -- PK = CompanyCd, ProductSalesCd
        ON b.CompanyCd = e.CompanyCd
           AND b.ProductSalesCd = e.ProductSalesCd 
    LEFT JOIN coUOM i -- PK = UOMId
        ON h.UOMId = i.UOMId 
    INNER JOIN coProductOldInformation j -- PK = CompanyCd, BFStatus, SpecCd
        ON a.CompanyCd = j.CompanyCd
            AND b.BFStatus = j.BFStatus
            AND b.ProductSalesCd = j.ProductSalesCd
    INNER JOIN coProductGroup1 g1 -- PK = CompanyCd, ProductCategoryCd, UsedDepartment, ProductGroup1Cd
        ON e.ProductGroup1Cd  = g1.ProductGroup1Cd
    INNER JOIN coProductGroup2 g2 -- PK = CompanyCd, ProductCategoryCd, UsedDepartment, ProductGroup2Cd
        ON e.ProductGroup1Cd  = g2.ProductGroup1Cd
Anonim
sumber
1
Apakah Anda memproyeksikan atribut dari coUOM? Jika tidak, Anda mungkin dapat menggunakan semi gabung. Jika ya, Anda bisa menggunakan UNIONsebagai alternatif. Memposting hanya FROMklausa Anda tidak cukup informasi di sini.
onedaywhen
1
Saya sudah sering bertanya-tanya ini (karena saya melihat sepanjang waktu).
Paul Draper
1
Apakah Anda melewatkan Pesanan Dengan dalam skema singkat Anda? Saya baru-baru ini menghadapi masalah ketika mengubah INNER JOIN ke LEFT OUTER JOIN mempercepat kueri dari 3 menit menjadi 10 detik. Jika Anda benar-benar memiliki Pesanan Menurut di kueri Anda, saya akan menjelaskan lebih lanjut sebagai jawaban. Sepertinya semua jawaban tidak benar-benar menjelaskan kasus yang saya hadapi.
Phuah Yee Keat

Jawaban:

403

A LEFT JOINsama sekali tidak lebih cepat dari INNER JOIN. Bahkan, ini lebih lambat; menurut definisi, gabungan luar ( LEFT JOINatau RIGHT JOIN) harus melakukan semua pekerjaan INNER JOINditambah pekerjaan tambahan dari null-memperluas hasil. Itu juga akan diharapkan untuk mengembalikan lebih banyak baris, lebih lanjut meningkatkan total waktu eksekusi hanya karena ukuran yang lebih besar dari hasil yang ditetapkan.

(Dan bahkan jika LEFT JOIN itu lebih cepat dalam spesifik situasi karena beberapa sulit-untuk-membayangkan pertemuan faktor, tidak fungsional setara dengan INNER JOIN, sehingga Anda tidak bisa hanya pergi mengganti semua contoh dari satu dengan yang lain!)

Kemungkinan besar masalah kinerja Anda terletak di tempat lain, seperti tidak memiliki kunci kandidat atau kunci asing diindeks dengan benar. 9 tabel cukup banyak untuk bergabung sehingga perlambatan bisa benar-benar hampir di mana saja. Jika Anda memposting skema Anda, kami mungkin dapat memberikan detail lebih lanjut.


Edit:

Merenungkan lebih lanjut tentang ini, saya bisa memikirkan satu keadaan di mana a LEFT JOINmungkin lebih cepat daripada INNER JOIN, dan saat itulah:

  • Beberapa tabel sangat kecil (katakanlah, di bawah 10 baris);
  • Tabel tidak memiliki indeks yang cukup untuk memenuhi permintaan.

Pertimbangkan contoh ini:

CREATE TABLE #Test1
(
    ID int NOT NULL PRIMARY KEY,
    Name varchar(50) NOT NULL
)
INSERT #Test1 (ID, Name) VALUES (1, 'One')
INSERT #Test1 (ID, Name) VALUES (2, 'Two')
INSERT #Test1 (ID, Name) VALUES (3, 'Three')
INSERT #Test1 (ID, Name) VALUES (4, 'Four')
INSERT #Test1 (ID, Name) VALUES (5, 'Five')

CREATE TABLE #Test2
(
    ID int NOT NULL PRIMARY KEY,
    Name varchar(50) NOT NULL
)
INSERT #Test2 (ID, Name) VALUES (1, 'One')
INSERT #Test2 (ID, Name) VALUES (2, 'Two')
INSERT #Test2 (ID, Name) VALUES (3, 'Three')
INSERT #Test2 (ID, Name) VALUES (4, 'Four')
INSERT #Test2 (ID, Name) VALUES (5, 'Five')

SELECT *
FROM #Test1 t1
INNER JOIN #Test2 t2
ON t2.Name = t1.Name

SELECT *
FROM #Test1 t1
LEFT JOIN #Test2 t2
ON t2.Name = t1.Name

DROP TABLE #Test1
DROP TABLE #Test2

Jika Anda menjalankan ini dan melihat rencana eksekusi, Anda akan melihat bahwa INNER JOINpermintaan memang lebih mahal daripada LEFT JOIN, karena memenuhi dua kriteria di atas. Itu karena SQL Server ingin melakukan hash cocok untuk INNER JOIN, tetapi tidak bersarang loop untuk LEFT JOIN; yang pertama biasanya jauh lebih cepat, tetapi karena jumlah baris sangat kecil dan tidak ada indeks untuk digunakan, operasi hashing ternyata menjadi bagian paling mahal dari permintaan.

Anda dapat melihat efek yang sama dengan menulis program dalam bahasa pemrograman favorit Anda untuk melakukan banyak pencarian pada daftar dengan 5 elemen, vs. tabel hash dengan 5 elemen. Karena ukurannya, versi tabel hash sebenarnya lebih lambat. Tetapi tingkatkan menjadi 50 elemen, atau 5000 elemen, dan versi daftar melambat menjadi perayapan, karena itu O (N) vs O (1) untuk hashtable.

Tetapi ubah kueri ini menjadi pada IDkolom alih-alih Namedan Anda akan melihat cerita yang sangat berbeda. Dalam hal ini, ia melakukan loop bersarang untuk kedua kueri, tetapi INNER JOINversi ini dapat menggantikan salah satu pemindaian indeks berkerumun dengan sebuah pencarian - yang berarti bahwa ini akan benar-benar menjadi urutan besarnya lebih cepat dengan sejumlah besar baris.

Jadi kesimpulannya kurang lebih seperti yang saya sebutkan beberapa paragraf di atas; ini hampir pasti masalah pengindeksan atau cakupan indeks, mungkin dikombinasikan dengan satu atau lebih tabel yang sangat kecil. Itulah satu-satunya keadaan di mana SQL Server kadang-kadang mungkin memilih rencana eksekusi yang lebih buruk untuk INNER JOINdaripada LEFT JOIN.

Aaronaught
sumber
4
Ada skenario lain yang dapat menyebabkan GABUNGAN OUTER berkinerja lebih baik daripada Gabung INNER. Lihat jawaban saya di bawah ini.
dbenham
12
Saya ingin menunjukkan bahwa pada dasarnya tidak ada dokumentasi basis data untuk mendukung gagasan bahwa inner joins dan outer joins kinerja berbeda. Gabungan luar sedikit lebih mahal daripada gabungan dalam, karena volume data dan ukuran hasil yang ditetapkan. Namun, algoritma yang mendasarinya ( msdn.microsoft.com/en-us/library/ms191426(v=sql.105).aspx ) adalah sama untuk kedua jenis gabungan. Kinerja harus sama ketika mereka mengembalikan jumlah data yang serupa.
Gordon Linoff
3
@Aonaonaught. . . Jawaban ini direferensikan dalam komentar yang mengatakan sesuatu yang menyatakan bahwa "gabungan luar berkinerja lebih buruk daripada gabungan dalam". Saya berkomentar hanya untuk memastikan bahwa kesalahpahaman ini tidak menyebar.
Gordon Linoff
16
Saya pikir jawaban ini menyesatkan dalam satu aspek penting: Karena ini menyatakan "A LEFT JOIN sama sekali tidak lebih cepat daripada INNER JOIN". Baris ini tidak benar. Secara teori tidak lebih cepat dari INNER JOIN. Hal ini tidak "benar-benar tidak lebih cepat." Pertanyaannya adalah pertanyaan kinerja. Dalam praktiknya sekarang saya telah melihat beberapa sistem (oleh perusahaan yang sangat besar!) Di mana INNER JOIN sangat lambat dibandingkan dengan OUTER JOIN. Teori dan praktik adalah hal yang sangat berbeda.
David Frenkel
5
@ DavidFrenkel: Itu sangat tidak mungkin. Saya akan meminta untuk melihat perbandingan A / B, dengan rencana eksekusi, jika Anda yakin perbedaan itu mungkin terjadi. Mungkin ini terkait dengan permintaan cache / rencana eksekusi, atau statistik yang buruk.
Aaronaught
127

Ada satu skenario penting yang dapat menyebabkan sambungan luar menjadi lebih cepat daripada sambungan batin yang belum dibahas.

Saat menggunakan gabungan luar, optimizer selalu bebas untuk menjatuhkan tabel gabungan luar dari rencana eksekusi jika kolom gabungan adalah PK dari tabel luar, dan tidak ada kolom tabel luar yang dirujuk di luar gabungan luar itu sendiri. Sebagai contoh SELECT A.* FROM A LEFT OUTER JOIN B ON A.KEY=B.KEYdan B.KEY adalah PK untuk B. Baik Oracle (saya percaya saya menggunakan rilis 10) dan Sql Server (saya menggunakan 2008 R2) memangkas tabel B dari rencana eksekusi.

Hal yang sama tidak selalu benar untuk gabungan dalam: SELECT A.* FROM A INNER JOIN B ON A.KEY=B.KEYmungkin atau mungkin tidak memerlukan B dalam rencana eksekusi tergantung pada kendala apa yang ada.

Jika A.KEY adalah kunci asing nullable yang mereferensikan B.KEY, maka pengoptimal tidak dapat menjatuhkan B dari rencana karena harus mengkonfirmasi bahwa ada baris B untuk setiap baris A.

Jika A.KEY adalah kunci asing kunci yang mereferensikan B.KEY, maka pengoptimal bebas untuk menjatuhkan B dari rencana karena kendala menjamin keberadaan baris. Tetapi hanya karena pengoptimal dapat menjatuhkan tabel dari rencana, tidak berarti itu akan berhasil. SQL Server 2008 R2 TIDAK menjatuhkan B dari paket. Oracle 10 TIDAK menjatuhkan B dari rencana. Sangat mudah untuk melihat bagaimana bergabung luar akan melakukan bergabung dalam SQL Server dalam kasus ini.

Ini adalah contoh sepele, dan tidak praktis untuk kueri yang berdiri sendiri. Mengapa bergabung dengan sebuah meja jika Anda tidak perlu?

Tapi ini bisa menjadi pertimbangan desain yang sangat penting saat mendesain tampilan. Sering kali tampilan "do-everything" dibangun yang menggabungkan semua yang mungkin perlu pengguna terkait dengan tabel pusat. (Terutama jika ada pengguna naif yang melakukan kueri ad-hoc yang tidak memahami model relasional) Tampilan dapat mencakup semua kolom relevan dari banyak tabel. Tetapi pengguna akhir hanya dapat mengakses kolom dari subset dari tabel dalam tampilan. Jika tabel digabungkan dengan gabungan luar, maka pengoptimal dapat (dan memang) menjatuhkan tabel yang tidak diperlukan dari rencana.

Sangat penting untuk memastikan bahwa tampilan menggunakan gabungan luar memberikan hasil yang benar. Seperti yang Aaronaught katakan - Anda tidak bisa secara buta mengganti OUTER JOIN dengan INNER JOIN dan mengharapkan hasil yang sama. Tetapi ada kalanya hal itu berguna untuk alasan kinerja saat menggunakan tampilan.

Satu catatan terakhir - Saya belum menguji dampak pada kinerja di atas, tetapi secara teori tampaknya Anda harus dapat dengan aman mengganti INNER JOIN dengan OUTER JOIN jika Anda juga menambahkan kondisi <FOREIGN_KEY> TIDAK NULL ke klausa mana.

dbenham
sumber
5
Saya benar-benar mengalami masalah ini ketika membangun pertanyaan yang sangat dinamis. Saya telah meninggalkan INNER JOIN yang saya gunakan dan tidak mengambil data dari, dan ketika saya beralih ke JOIN KIRI (karena penasaran geser) permintaan sebenarnya berjalan lebih cepat.
Erik Philips
1
EDIT - Mengklarifikasi kondisi yang harus ada untuk optimizer untuk menjatuhkan tabel gabungan luar dari rencana eksekusi.
dbenham
2
Satu klarifikasi kecil untuk jawaban Anda: Ketika kolom kunci asing tidak dapat dibatalkan, INNER JOIN dan LEFT JOIN menjadi setara secara semantik (yaitu klausa WHERE yang Anda sarankan berlebihan); satu-satunya perbedaan adalah rencana eksekusi.
Douglas
2
Meskipun ini menunjukkan contoh yang tampaknya sepele, ini adalah jawaban yang sangat luar biasa!
pbalaga
6
+1: Saya sepertinya mengalami beberapa pertanyaan di mana saya menggunakan gabungan dalam dengan beberapa tabel yang sangat besar. Gabungan dalam menyebabkan tumpahan ke tempdb dalam rencana kueri (saya berasumsi karena alasan yang disebutkan di atas - dan server saya kekurangan RAM untuk menampung semua yang ada dalam memori). Beralih ke gabungan kiri menghilangkan tumpahan ke tempdb, akibatnya adalah bahwa beberapa kueri 20-30 detik saya sekarang berjalan dalam pecahan satu detik. Ini adalah gotcha yang sangat penting karena kebanyakan orang tampaknya membuat asumsi selimut bahwa gabungan batin lebih cepat.
phosplait
23

Jika semuanya berfungsi sebagaimana mestinya tidak seharusnya, TETAPI kita semua tahu segalanya tidak berjalan seperti seharusnya terutama ketika menyangkut pengoptimal kueri, caching rencana kueri, dan statistik.

Pertama saya akan menyarankan untuk membangun kembali indeks dan statistik, kemudian membersihkan cache rencana kueri hanya untuk memastikan itu tidak mengacaukan segalanya. Namun saya sudah mengalami masalah bahkan ketika itu selesai.

Saya pernah mengalami beberapa kasus di mana join kiri lebih cepat daripada join internal.

Alasan yang mendasarinya adalah ini: Jika Anda memiliki dua tabel dan Anda bergabung pada kolom dengan indeks (pada kedua tabel). Gabungan dalam akan menghasilkan hasil yang sama tidak masalah jika Anda mengulang entri dalam indeks pada tabel satu dan mencocokkan dengan indeks pada tabel dua seolah-olah Anda akan melakukan sebaliknya: Loop atas entri dalam indeks pada tabel dua dan cocok dengan indeks dalam tabel satu. Masalahnya adalah ketika Anda memiliki statistik yang menyesatkan, pengoptimal kueri akan menggunakan statistik indeks untuk menemukan tabel dengan entri yang paling tidak cocok (berdasarkan kriteria Anda yang lain). Jika Anda memiliki dua tabel dengan 1 juta di masing-masing, dalam tabel satu Anda memiliki 10 baris yang cocok dan di tabel dua Anda memiliki 100000 baris yang cocok. Cara terbaik adalah melakukan pemindaian indeks pada tabel satu dan mencocokkan 10 kali dalam tabel dua. Kebalikannya adalah pemindaian indeks yang loop lebih dari 100000 baris dan mencoba untuk mencocokkan 100000 kali dan hanya 10 berhasil. Jadi, jika statistik tidak benar, pengoptimal mungkin memilih tabel yang salah dan indeks untuk diulang.

Jika optimizer memilih untuk mengoptimalkan gabung kiri dalam urutan yang tertulis itu akan berkinerja lebih baik daripada gabung dalam.

NAMUN, pengoptimal juga dapat mengoptimalkan gabung kiri secara kurang optimal sebagai gabung semi kiri. Untuk membuatnya memilih yang Anda inginkan, Anda dapat menggunakan petunjuk urutan kekuatan.

Kvasi
sumber
18

Coba kedua pertanyaan (yang dengan bagian dalam dan kiri bergabung) dengan OPTION (FORCE ORDER)di akhir dan memposting hasilnya. OPTION (FORCE ORDER)adalah petunjuk kueri yang memaksa optimizer untuk membangun rencana eksekusi dengan pesanan gabungan yang Anda berikan dalam kueri.

Jika INNER JOINmulai bekerja secepat LEFT JOIN, itu karena:

  • Dalam kueri yang seluruhnya disusun oleh INNER JOINs, urutan bergabung tidak masalah. Ini memberikan kebebasan bagi optimizer kueri untuk memesan gabungan yang dianggapnya sesuai, sehingga masalahnya mungkin bergantung pada optimizer.
  • Dengan LEFT JOIN, bukan itu masalahnya karena mengubah urutan bergabung akan mengubah hasil kueri. Ini berarti mesin harus mengikuti urutan bergabung yang Anda berikan pada kueri, yang mungkin lebih baik daripada yang dioptimalkan.

Tidak tahu apakah ini menjawab pertanyaan Anda, tetapi saya pernah berada di sebuah proyek yang menampilkan pertanyaan yang sangat rumit membuat perhitungan, yang benar-benar mengacaukan pengoptimal. Kami memiliki kasus di mana a FORCE ORDERakan mengurangi waktu eksekusi permintaan dari 5 menit menjadi 10 detik.

Francisco Pires
sumber
9

Telah melakukan sejumlah perbandingan antara gabungan luar dan dalam kiri dan belum dapat menemukan perbedaan yang konsisten. Ada banyak variabel. Sedang mengerjakan database pelaporan dengan ribuan tabel banyak dengan banyak bidang, banyak perubahan seiring waktu (versi vendor dan alur kerja lokal). Tidak mungkin membuat semua kombinasi indeks penutup untuk memenuhi kebutuhan beragam pertanyaan dan menangani data historis. Telah melihat permintaan dalam yang mematikan kinerja server karena dua tabel besar (jutaan hingga puluhan juta baris) digabungkan untuk menarik sejumlah besar bidang dan tidak ada indeks penutup.

Namun masalah terbesar, tampaknya tidak cocok dalam diskusi di atas. Mungkin basis data Anda dirancang dengan baik dengan pemicu dan pemrosesan transaksi yang dirancang dengan baik untuk memastikan data yang baik. Milik saya sering memiliki nilai NULL yang tidak diharapkan. Ya, definisi tabel bisa memberlakukan no-Nulls tetapi itu bukan opsi di lingkungan saya.

Jadi pertanyaannya adalah ... apakah Anda mendesain kueri hanya untuk kecepatan, prioritas yang lebih tinggi untuk pemrosesan transaksi yang menjalankan kode yang sama ribuan kali dalam satu menit. Atau apakah Anda mencari keakuratan yang akan disediakan oleh sambungan luar kiri. Ingatlah bahwa gabungan internal harus menemukan kecocokan di kedua sisi, sehingga NULL yang tidak terduga tidak hanya akan menghapus data dari dua tabel tetapi juga seluruh baris informasi. Dan itu terjadi dengan sangat baik, tidak ada pesan kesalahan.

Anda bisa sangat cepat karena mendapatkan 90% dari data yang dibutuhkan dan tidak menemukan sambungan dalam telah menghapus informasi secara diam-diam. Kadang-kadang gabungan batin bisa lebih cepat, tetapi saya tidak percaya ada orang yang membuat asumsi itu kecuali mereka telah meninjau rencana eksekusi. Kecepatan itu penting, tetapi akurasi lebih penting.

JO
sumber
8

Masalah kinerja Anda lebih cenderung karena jumlah gabungan yang Anda lakukan dan apakah kolom yang Anda ikuti memiliki indeks atau tidak.

Kasus terburuk Anda dapat dengan mudah melakukan 9 scan seluruh tabel untuk setiap bergabung.

eddiegroves
sumber
7

Gabungan luar dapat menawarkan kinerja superior saat digunakan dalam tampilan.

Katakanlah Anda memiliki kueri yang melibatkan tampilan, dan tampilan itu terdiri dari 10 tabel yang digabungkan. Katakanlah permintaan Anda hanya terjadi menggunakan kolom dari 3 dari 10 tabel itu.

Jika 10 tabel tersebut telah digabungkan bersama, maka pengoptimal kueri harus menggabungkan semuanya meskipun kueri Anda sendiri tidak memerlukan 7 dari 10 tabel. Itu karena bagian dalam bergabung sendiri mungkin menyaring data, membuat mereka penting untuk dihitung.

Jika 10 tabel tersebut telah digabungkan bersama, maka pengoptimal kueri hanya akan benar-benar bergabung dengan yang diperlukan: 3 dari 10 di antaranya dalam kasus ini. Itu karena gabungan itu sendiri tidak lagi memfilter data, dan dengan demikian gabungan yang tidak terpakai dapat dilewati.

Sumber: http://www.sqlservercentral.com/blogs/sql_coach/2010/07/29/poor-little-misunderstood-views/

MarredCheese
sumber
1
Pernyataan Anda tentang "gabungan luar" menyesatkan dan berpotensi salah. Luar berarti bahwa data di sisi lain tidak perlu ada - dan jika tidak menggantikan NULL. Dalam keadaan tertentu RDBMS dapat "melewati" mereka (lihat jawaban di atas dari dbenham). NAMUN - luar vs dalam dapat menyebabkan permintaan Anda mengembalikan hasil yang sangat berbeda. INNER berarti - memberikan hasil yang item dalam KEDUA A & B. LEFT OUTER berarti semua A, dan opsional B jika ada. Kasus pertama - Anda mendapatkan beberapa baris, di detik Anda mendapatkan SEMUA baris.
ripvlan
1
@ripvlan Tentu saja, gabungan luar dan dalam tidak selalu dapat dipertukarkan. Pertanyaan aslinya adalah tentang kinerja, yang menyiratkan bahwa kita sedang berbicara tentang kasus di mana salah satu gabung akan mengembalikan set hasil yang sama.
MarredCheese
1
Ya dan - OUTER dapat menyebabkan masalah kinerja karena akan menyebabkan semua baris (lebih banyak data) dikembalikan. Asumsi Anda bahwa hasil query dalam output yang sama adalah adil - namun itu tidak benar dalam kasus umum dan spesifik untuk setiap desain db. Dan bagi mereka yang tidak 100% akrab dengan aljabar relasional dapat menyebabkan mereka sedih. Maksud saya hanya untuk menawarkan lebih banyak wawasan kepada orang-orang yang membaca ini mencari saran dan bahwa KIRI / KANAN tidak akan secara ajaib menyelesaikan masalah dan dapat menyebabkan lebih banyak masalah. Ini adalah kekuatan yang tersisa untuk level 300 :-)
ripvlan
2

Saya menemukan sesuatu yang menarik di SQL server ketika memeriksa apakah gabungan lebih cepat dari gabungan kiri.

Jika Anda tidak menyertakan item dari tabel gabungan kiri, dalam pernyataan pilih, gabungan kiri akan lebih cepat daripada permintaan yang sama dengan gabungan dalam.

Jika Anda menyertakan tabel gabungan kiri dalam pernyataan pilih, gabungan dalam dengan kueri yang sama sama atau lebih cepat dari gabungan kiri.

Buzzzzzzz
sumber
0

Dari perbandingan saya, saya menemukan bahwa mereka memiliki rencana eksekusi yang sama persis. Ada tiga skenario:

  1. Jika dan ketika mereka mengembalikan hasil yang sama, mereka memiliki kecepatan yang sama. Namun, kita harus ingat bahwa mereka bukan pertanyaan yang sama, dan LEFT JOIN mungkin akan memberikan lebih banyak hasil (ketika beberapa kondisi ON tidak terpenuhi) --- inilah mengapa biasanya lebih lambat.

  2. Ketika tabel utama (non-const pertama dalam rencana eksekusi) memiliki kondisi terbatas (WHERE id =?) Dan kondisi ON terkait pada nilai NULL, tabel "kanan" tidak digabungkan --- ini adalah saat LEFT JOIN lebih cepat.

  3. Seperti dibahas dalam Poin 1, biasanya INNER JOIN lebih membatasi dan mengembalikan hasil lebih sedikit dan karenanya lebih cepat.

Keduanya menggunakan indeks (sama).

Jiulin Teng
sumber