MENGGUNAKAN konstruk dalam klausa JOIN dapat memperkenalkan hambatan optimasi dalam kasus-kasus tertentu?


35

Saya memperhatikan bahwa USINGkonstruk (alih-alih ON) dalam FROMklausa SELECTkueri dapat menimbulkan hambatan optimisasi dalam kasus tertentu.

Maksud saya kata kunci ini:

PILIH *
Dari
GABUNG b MENGGUNAKAN (a_id)

Hanya dalam kasus yang lebih kompleks.

Konteks: komentar ini untuk pertanyaan ini .

Saya menggunakan ini banyak dan tidak pernah melihat sesuatu yang begitu jauh. Saya akan sangat tertarik pada kasus uji yang menunjukkan efek atau tautan apa pun ke informasi lebih lanjut. Upaya pencarian saya kosong.

Jawaban yang sempurna akan menjadi ujian untuk ditunjukkan USING (a_id)dengan kinerja yang lebih rendah bila dibandingkan dengan klausa gabungan alternatif ON a.a_id = b.a_id- jika itu benar-benar dapat terjadi.


2
@ kgrittn: Itulah yang umumnya saya harapkan sejauh ini: itu USINGsedikit lebih cepat - karena menghasilkan satu kolom kurang dalam matriks hasil. Temuan Anda berasal dari tahun 2005 dan 2008. Saya berasumsi masalah apa pun telah diperbaiki sekarang. Namun , saya dapat melihat batasan yang mungkin: BERGABUNG dengan USINGmungkin harus diterapkan secara berurutan , karena kolom gabungan yang dihasilkan adalah produk bersama. Dengan demikian berpotensi membatasi opsi dalam menata ulang GABUNG.
Erwin Brandstetter

1
Saya menemukan utas ini yang mungkin ada hubungannya dengan menunda saya menggunakannya sesering yang saya miliki, karena VIEW dengan kondisi PENGGUNAAN pada gabungan dapat menyebabkan masalah pada dump / restore: archives.postgresql.org/pgsql- bugs / 2011-06 / msg00030.php Saya masih memiliki perasaan yang mengganggu ada utas lain terkait dengan masalah kinerja dengan MENGGUNAKAN di mana solusinya adalah untuk menggunakan ON, tapi saya akan menyerah untuk menemukannya, saya pikir. Mungkin aman untuk menggunakannya di luar tampilan dan ingat untuk mencoba HIDUP sebagai langkah diagnostik jika permintaan lambat.
kgrittn

1
Sepertinya "menggunakan" membuat kode sedikit terbaca tetapi saya kira kedua bidang membutuhkan nama yang sama. Saya tidak berpikir bahwa menggunakan akan memiliki kinerja yang lebih baik daripada "on", karena DB perlu membuat pertandingan, itu seperti pilih memiliki kinerja yang sama daripada bergabung (koreksi saya jika saya salah), Perbedaannya adalah bahwa Bergabung lebih bersih dan lebih mudah dipertahankan.
jcho360

2
@ HLGEM: Itu hanya nama simbolis, dan hanya dengan dua tabel, seperti dalam contoh saya, tidak ada ruang untuk kebingungan. Namun, saya mengubah pertanyaan itu. Tidak ingin mendorong penggunaan idnama kolom yang tidak menguntungkan .
Erwin Brandstetter

2
@ChristiaanWesterbeek: Saya tidak setuju. "Masuk ke tempat" untuk jawaban Postgres yang mendalam adalah (masih) mengirim surat. Hanya sedikit pengembang Postgres yang aktif di SO, tetapi semua pengembang dan pakar Postgres membaca milis
a_horse_with_no_name

Jawaban:


12

Erwin: Saya setuju dengan gagasan bahwa MENGGUNAKAN yang menyebabkan pemesanan yang kaku dapat membuat banyak kasus tepi di mana rencana optimal akan dikesampingkan. Saya baru-baru ini membantu seseorang yang memiliki sesuatu seperti ini dalam permintaannya:

LEFT JOIN ( 
     a 
     JOIN b ON a.id = b.a_id
     JOIN c ON b.c_id = c.id
) ON a.id = something.a_id
LEFT JOIN (
     table1 t1
     JOIN table2 t2 ON t1.some_field = t2.other_field
     JOIN talbe3 t3 ON t2.yafield = t3.something_else
) ON ....
repeat a few more times

Dalam kasusnya yang terburuk dari blok gabungan ini menyebabkan loop bersarang melalui sekitar 200 ribu baris, sekitar 20 ribu kali (lakukan perhitungan), dan karena kunci tidak dapat ditekan ke indeks, itu adalah pemindaian berurutan. Ini berarti bahwa keseluruhan permintaan memakan waktu sekitar 3 jam untuk dijalankan karena perubahan rencana cascading. Dengan mendistribusikan gabungan kiri, tombol dapat ditekan ke bawah dan kueri berjalan dalam hitungan detik. Tentu saja ini tidak persis sama, itulah sebabnya perencana itu tidak dapat memperlakukan mereka sebagai setara sehingga dibiarkan mencari tahu rencana itu sebagai hash bergabung dan kemudian melakukan loop bersarang di, yang sangat lambat.

Setiap kali Anda secara kaku memaksa sambungan untuk melewati dalam urutan tertentu Anda memperkenalkan kasus-kasus di mana informasi filter utama mungkin belum tersedia dalam pelaksanaan rencana, dan apa yang mungkin dilakukan kemudian dalam pemindaian indeks cepat / hash bergabung mungkin harus dilakukan jauh lebih lambat dalam loop berulang / sekuensial pemindaian dan jadi sementara fragmen di atas tidak langsung setara, itu menunjukkan masalah yang sama.

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.