Mengingat pertanyaan ini pada reddit, saya membersihkan kueri untuk menunjukkan di mana masalahnya berada dalam kueri. Saya menggunakan koma terlebih dahulu dan WHERE 1=1
untuk membuat memodifikasi kueri lebih mudah, jadi pertanyaan saya umumnya berakhir seperti ini:
SELECT
C.CompanyName
,O.ShippedDate
,OD.UnitPrice
,P.ProductName
FROM
Customers as C
INNER JOIN Orders as O ON C.CustomerID = O.CustomerID
INNER JOIN [Order Details] as OD ON O.OrderID = OD.OrderID
INNER JOIN Products as P ON P.ProductID = OD.ProductID
Where 1=1
-- AND O.ShippedDate Between '4/1/2008' And '4/30/2008'
And P.productname = 'TOFU'
Order By C.CompanyName
Seseorang pada dasarnya mengatakan bahwa 1 = 1 umumnya malas dan buruk untuk kinerja .
Mengingat bahwa saya tidak ingin "mengoptimalkan secara prematur" - saya ingin mengikuti praktik yang baik. Saya telah melihat rencana permintaan sebelumnya, tetapi umumnya hanya untuk mengetahui indeks apa yang dapat saya tambahkan (atau sesuaikan) untuk membuat kueri saya berjalan lebih cepat.
Pertanyaannya kemudian ... apakah Where 1=1
hal-hal buruk terjadi? Dan jika demikian, bagaimana saya bisa tahu?
Sunting Minor: Saya selalu 'berasumsi' juga yang 1=1
akan dioptimalkan, atau paling tidak dapat diabaikan. Tidak ada salahnya untuk menanyakan mantra, seperti "Goto's is Evil" atau "Premature Optimization ..." atau fakta yang diasumsikan lainnya. Tidak yakin apakah 1=1 AND
akan memengaruhi rencana kueri secara realistis atau tidak. Bagaimana dengan di subqueries? CTE? Prosedur?
Saya bukan orang yang dioptimalkan, kecuali diperlukan ... tetapi jika saya melakukan sesuatu yang sebenarnya "buruk", saya ingin meminimalkan efek atau mengubah di mana berlaku.
sumber
Jawaban:
SQL Server
penguraioptimizer memiliki fitur yang disebut "Konstan Lipat" yang menghilangkan ekspresi tautologis dari permintaan.Jika Anda melihat rencana eksekusi, di mana saja di predikat Anda akan melihat ekspresi itu muncul. Ini menyiratkan bahwa pelipatan konstan tetap dilakukan pada waktu kompilasi untuk alasan ini dan lainnya dan tidak berpengaruh pada kinerja kueri.
Lihat Evaluasi Konstan Lipat dan Ekspresi Selama Estimasi Kardinalitas untuk info lebih lanjut.
sumber
Penambahan predikat redundan dapat membuat perbedaan dalam SQL Server.
Dalam rencana pelaksanaan di bawah perhatikan
@1
dalam rencana pertama vs literal'foo'
dalam rencana kedua.Ini menunjukkan bahwa SQL Server dianggap sebagai permintaan pertama untuk parameterisasi sederhana untuk mempromosikan penggunaan kembali rencana eksekusi - namun perbandingan dua konstanta mencegah hal ini terjadi dalam kasus kedua.
Daftar kondisi yang mencegah parameterisasi sederhana (sebelumnya dikenal sebagai parameterisasi otomatis) dapat ditemukan di Lampiran A dari Caching Paket Dokumen Teknis Microsoft:
parameterisasi sederhana umumnya bukanlah sesuatu yang harus Anda andalkan. Jauh lebih baik untuk parameterisasi pertanyaan Anda secara eksplisit.
sumber
Dalam RDBMS modern apa pun (termasuk Oracle, Microsoft SQL Server, dan PostgreSQL - saya yakin akan hal ini) ini tidak akan berpengaruh pada kinerja.
Seperti yang dicatat seseorang, ini hanya akan memengaruhi fase perencanaan kueri. Karenanya perbedaan hanya akan terlihat ketika Anda menjalankan ribuan iterasi dari kueri sederhana yang tidak mengembalikan data apa pun, seperti ini:
Bagi saya, pada PostgreSQL 9.0, ini terlihat hanya dengan 10.000 iterasi:
sumber
Ini bisa menjadi "masalah" untuk Oracle ketika Anda menggunakan parameter database cursor_sharing. Ketika ini diatur ke "memaksa" itu akan mengubah semua pernyataan SQL. Semua "konstanta" dalam kueri akan diganti oleh variabel bind (seperti 1 =>: SYS_0).
Opsi ini diperkenalkan untuk berurusan dengan beberapa pengembang yang malas. Di sisi lain itu juga dapat membahayakan pengembang malas lainnya. Namun risikonya tidak terlalu tinggi. Sejak 11g ia memiliki fitur peeking peind variable.
sumber