Baik, Buruk atau Biasa saja: DIMANA 1 = 1


14

Mengingat pertanyaan ini pada reddit, saya membersihkan kueri untuk menunjukkan di mana masalahnya berada dalam kueri. Saya menggunakan koma terlebih dahulu dan WHERE 1=1untuk 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=1hal-hal buruk terjadi? Dan jika demikian, bagaimana saya bisa tahu?

Sunting Minor: Saya selalu 'berasumsi' juga yang 1=1akan 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 ANDakan 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.


2
Tidak, tidak akan. Terlepas dari beberapa mikrodetik untuk pengoptimal untuk menghapus kondisi yang berlebihan. Anda lebih baik fokus pada literal tanggal Anda tidak ambigu.
ypercubeᵀᴹ

Seperti yang dikatakan @ypercube, tidak ada bedanya. Pengoptimal kueri harus menjadi bagian dari **** untuk hal seperti itu untuk membuat perbedaan;)
Philᵀᴹ

4
Jangan percaya semua yang Anda baca di reddit. Silahkan.
Aaron Bertrand

1
@ AaronBertrand Saya mengambil semuanya dengan sebutir garam, sampai saya mengalaminya langsung. Saya masih akan mengambil pertanyaan yang kedengarannya masuk akal dan melihat apakah ada kebenaran di dalamnya, terutama ketika itu memengaruhi pekerjaan saya sehari-hari.
WernerCD

4
Ada butiran garam, lalu ada kandungan garam dari seluruh lautan yang ditimbun di atas gedung kantor Anda: P
Philᵀᴹ

Jawaban:


13

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.


Mungkin dikompilasi karena ini adalah pola yang diketahui untuk melakukan penggabungan bidang.
jcolebrand

Tidak, ini dikompilasi karena tautologis. Ini akan bekerja dengan cara yang sama dengan 2736 = 2736, yang tidak hanya seperti biasa seperti 1 = 1. Hal yang sama berlaku untuk kontradiksi. Dalam hal ini fitur ini disebut "Deteksi kontradiksi".
spaghettidba

Bagian mana dari "pola diketahui" yang berarti "harus 1 = 1"?
jcolebrand

9

Penambahan predikat redundan dapat membuat perbedaan dalam SQL Server.

Dalam rencana pelaksanaan di bawah perhatikan @1dalam rencana pertama vs literal 'foo'dalam rencana kedua.

masukkan deskripsi gambar di sini

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.


4

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:

SELECT 1 FROM empty_table; -- run this 10 000 times.

SELECT 1 FROM empty_table WHERE 1=1; -- run this 10 000 times and compare.

Bagi saya, pada PostgreSQL 9.0, ini terlihat hanya dengan 10.000 iterasi:

filip@srv:~$ pgquerybench.pl -h /var/run/postgresql/ -q "select 1 from never where 1=1" -q "select 1 from never" -i 10000
Iterations: 10000
Query:   select 1 from never where 1=1
Total:   2.952 s
Average: 0.295 ms
Query:   select 1 from never
Total:   2.850 s
Average: 0.285 ms

0

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.


Bisakah Anda mengklarifikasi apa "Sejak 11g ia memiliki fitur peeking variabel." cara?
ypercubeᵀᴹ

@ypercube "Bind variable peeking" berarti bahwa pengoptimal akan mengamati nilai aktual dari variabel bind dan menggunakan statistik data untuk mengevaluasi kembali dan mungkin membuat ulang rencana eksekusi permintaan. Saya ragu mengintip akan berpengaruh pada konstruk yang sedang dibahas, karena tidak tergantung pada statistik data.
mustaccio
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.