Misalkan saya memiliki tabel yang disebut PEOPLE
memiliki 3 kolom ID, LastName, FirstName
, tidak ada kolom ini yang diindeks.
LastName
lebih unik, dan FirstName
kurang unik.
Jika saya melakukan 2 pencarian:
select * from PEOPLE where FirstName="F" and LastName="L"
select * from PEOPLE where LastName="L" and FirstName="F"
Keyakinan saya adalah yang kedua lebih cepat karena kriteria yang lebih unik ( LastName
) muncul lebih dulu dalam where
klausa, dan rekaman akan dihilangkan dengan lebih efisien. Saya tidak berpikir pengoptimal cukup pintar untuk mengoptimalkan sql pertama.
Apakah pemahaman saya benar?
sql
performance
where-clause
Ziyang Zhang
sumber
sumber
Jawaban:
Tidak, urutan itu tidak masalah (atau setidaknya: seharusnya tidak menjadi masalah).
Pengoptimal kueri yang layak akan melihat semua bagian
WHERE
klausa dan mencari cara paling efisien untuk memenuhi kueri itu.Saya tahu pengoptimal kueri SQL Server akan memilih indeks yang sesuai - tidak peduli urutan mana Anda memiliki dua kondisi masuk Saya berasumsi RDBMS lain akan memiliki strategi serupa.
Yang menjadi masalah adalah apakah Anda memiliki indeks yang cocok untuk ini atau tidak!
Dalam kasus SQL Server, kemungkinan akan menggunakan indeks jika Anda memiliki:
(LastName, FirstName)
(FirstName, LastName)
(LastName)
, atau hanya(FirstName)
(atau keduanya)Di sisi lain - lagi untuk SQL Server - jika Anda menggunakan
SELECT *
untuk mengambil semua kolom dari tabel, dan tabelnya agak kecil, maka ada kemungkinan besar pengoptimal kueri hanya akan melakukan pemindaian tabel (atau indeks berkerumun) daripada menggunakan indeks (karena pencarian ke halaman data lengkap untuk mendapatkan semua kolom lain menjadi terlalu mahal dengan sangat cepat).sumber
WHERE T1.col_1/T2.col_2 > 10 AND T2.col_2 <> 0
dan mendapatDIVIDE BY 0
kesalahan. Setelah saya mengganti pesanan, kondisi kueri berhasil dieksekusi. Kemudian saya mengganti urutannya kembali sehingga saya berharap mendapatkan kesalahan lagi, tetapi kali ini berhasil! Pada akhirnya kesimpulan saya adalah bahwa untuk menjalankan pertama pesanan itu penting, sampai rencana eksekusi dibuat. Setelah itu pesanan tidak 'tidak masalah' karena pengoptimal / rencana eksekutif akan mengurusnyaUrutan klausa WHERE tidak boleh membuat perbedaan dalam database yang sesuai dengan standar SQL. Urutan evaluasi tidak dijamin di sebagian besar database.
Jangan berpikir bahwa SQL peduli dengan pesanan. Berikut ini menghasilkan kesalahan di SQL Server:
Jika bagian pertama dari klausa ini dieksekusi terlebih dahulu, maka hanya nama tabel numerik yang akan dicetak sebagai integer. Namun, gagal, memberikan contoh yang jelas bahwa SQL Server (seperti database lain) tidak peduli tentang urutan klausa dalam pernyataan WHERE.
sumber
ISNUMERIC(table_name) = 1
dievaluasi terlebih dahulu, makaCAST
hanya akan dipanggil untuk nama tabel numerik. Tapi karena tidak dievaluasi terlebih dahulu,CAST
dievaluasi untuk nama tabel non-numerik, juga, menyebabkan pesan kesalahan.ANSI SQL Draft 2003 5WD-01-Framework-2003-09.pdf
6.3.3.3 Urutan evaluasi aturan
...
Jika prioritas tidak ditentukan oleh Format atau tanda kurung, evaluasi ekspresi yang efektif biasanya dilakukan dari kiri ke kanan. Namun, bergantung pada implementasi apakah ekspresi benar-benar dievaluasi dari kiri ke kanan, terutama ketika operan atau operator dapat menyebabkan kondisi dimunculkan atau jika hasil ekspresi dapat ditentukan tanpa mengevaluasi semua bagian ekspresi sepenuhnya.
disalin dari sini
sumber
Tidak, semua RDBM pertama kali memulai dengan menganalisis kueri dan mengoptimalkannya dengan menyusun ulang klausa where Anda.
Bergantung pada RDBM mana yang Anda gunakan dapat menampilkan apa hasil analisis (cari penjelasan rencana di oracle misalnya)
M.
sumber
Pernyataan OP asli
Saya kira Anda membingungkan ini dengan memilih urutan kolom sambil membuat indeks di mana Anda harus meletakkan kolom yang lebih selektif terlebih dahulu daripada yang paling selektif kedua dan seterusnya.
BTW, untuk dua query SQL server optimizer di atas tidak akan melakukan optimasi apapun tetapi akan menggunakan paket Trivila selama total biaya rencana tersebut kurang dari biaya ambang batas paralelisme.
sumber
Sejauh ini benar, dengan asumsi nama tidak diindeks. Data yang berbeda akan membuatnya salah. Untuk mengetahui cara melakukannya, yang dapat berbeda setiap saat, DBMS harus menjalankan kueri penghitungan yang berbeda untuk setiap kolom dan membandingkan angkanya, yang akan menghabiskan biaya lebih dari sekadar mengangkat bahu dan melanjutkannya.
sumber