Apakah urutan klausa penting dalam SQL?


121

Misalkan saya memiliki tabel yang disebut PEOPLEmemiliki 3 kolom ID, LastName, FirstName, tidak ada kolom ini yang diindeks.
LastNamelebih unik, dan FirstNamekurang 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 whereklausa, dan rekaman akan dihilangkan dengan lebih efisien. Saya tidak berpikir pengoptimal cukup pintar untuk mengoptimalkan sql pertama.

Apakah pemahaman saya benar?


8
Tidak, urutan itu tidak masalah - setiap pengoptimal kueri yang layak akan melihat semua klausa WHERE dan mencari cara paling efisien untuk memenuhi kueri itu
marc_s

3
Apa pengamatan Anda ketika Anda menjalankan dua pernyataan ini? Seperti apa rencana eksekusinya?
Conrad Frix

3
Apakah Anda mengacu pada RDBMS tertentu? Memang ada perbedaan.
Bjoern


Jawaban:


101

Tidak, urutan itu tidak masalah (atau setidaknya: seharusnya tidak menjadi masalah).

Pengoptimal kueri yang layak akan melihat semua bagian WHEREklausa 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:

  • indeks (LastName, FirstName)
  • indeks (FirstName, LastName)
  • indeks hanya (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).


Jika tidak ada indeks (es) op bisa jadi benar, tergantung datanya. Tentu saja melakukan sesuatu seperti ini tanpa indeks, akan menjadi keputusan yang aneh ...
Tony Hopkinson

@TonyHopkinson: Saya rasa tidak - bahkan tanpa indeks saya ragu ada perbedaan sama sekali. Lagi pula: tanpa indeks, apa lagi selain pemindaian tabel lengkap yang dapat dilakukan RDBMS, benarkah ??
marc_s

2
Catatan samping yang menarik dengan SQL server, ternyata urutan TIDAK ADA dalam predikat sebenarnya dapat memengaruhi pembuatan rencana: bradsruminations.blogspot.com/2010/04/ looking
Justin Swartsel

3
Suatu hal yang aneh adalah bahwa untuk eksekusi pertama dari sebuah query, urutan kondisi dalam klausa WHERE PENTING! Saya memiliki dua kondisi, seperti: WHERE T1.col_1/T2.col_2 > 10 AND T2.col_2 <> 0dan mendapat DIVIDE BY 0kesalahan. 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 mengurusnya
Radu Gheorghiu

1
Saya suka Anda berkata, "... atau setidaknya: tidak penting" - Saya sangat setuju. Terkadang itu penting, sayangnya. Saya telah melihat kasus-kasus di mana SQL terlalu rumit untuk ditangani oleh pengoptimal dan, dan hal-hal seperti urutan kolom dan urutan tabel bergabung membuat perbedaan. Itu tergantung pada RDBMS, kompleksitas pernyataan SQL, dan bahkan rilisnya. SQL yang sangat kompleks dapat mengakibatkan keputusan pengoptimal yang buruk atau penggunaan default berkode keras dalam kode pengoptimal.
Victor Di Leo

19

Urutan 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:

select *
from INFORMATION_SCHEMA.TABLES
where ISNUMERIC(table_name) = 1 and CAST(table_name as int) <> 0

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.


Apa kueri yang menyebabkan kesalahan itu ada hubungannya dengan urutan evaluasi predikat WHERE?
Jim

7
@Jim Jika ISNUMERIC(table_name) = 1dievaluasi terlebih dahulu, maka CASThanya akan dipanggil untuk nama tabel numerik. Tapi karena tidak dievaluasi terlebih dahulu, CASTdievaluasi untuk nama tabel non-numerik, juga, menyebabkan pesan kesalahan.
hibbelig

2
Klarifikasi luar biasa
neeohw

Hanya untuk memastikan saya memeriksa apakah menukar kondisi akan menyebabkan SQL server menanganinya dengan cara lain, tetapi gagal di kedua sisi. Saya pikir ini bisa berarti salah satu dari dua hal: (1) Ini tidak mengoptimalkan sebaik mungkin atau (2) Ini adalah kesalahan waktu kompilasi dan SQL bahkan tidak mulai mencoba membandingkan apa pun, menalangi pendahuluan. Dugaan saya adalah bahwa itu nr. 2.
Louis Somers

9

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


2

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.


Itu dilakukan berdasarkan indeks. Jadi tidak langsung dalam hal konten.
Tony Hopkinson

1

Pernyataan OP asli

Keyakinan saya adalah yang kedua lebih cepat karena kriteria yang lebih unik (LastName) lebih dulu> klausa where, dan catatan akan dihilangkan dengan lebih efisien. Saya tidak berpikir pengoptimal> cukup pintar untuk mengoptimalkan sql pertama.

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.


0

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.

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.