Apakah “WHERE 1 = 1” biasanya berdampak pada kinerja permintaan?

19

Baru-baru ini saya melihat pertanyaan "di mana 1 = 1 pernyataan" ; sebuah konstruk SQL yang sering saya gunakan dalam membangun SQL dinamis dalam upaya untuk menulis kode yang lebih bersih (dari perspektif bahasa host).

Secara umum, apakah penambahan pada statemen SQL ini memengaruhi kinerja kueri secara negatif? Saya tidak mencari jawaban sehubungan dengan sistem basis data tertentu (karena saya telah menggunakannya dalam DB2, SQL Server, MS-Access, dan mysql) - kecuali tidak mungkin untuk menjawab tanpa masuk ke spesifikasi.

transistor1
sumber
4
Saya percaya pengoptimal mana pun akan dapat menangani kondisi sederhana seperti itu dan mengabaikannya sehingga rencana eksekusi akhir tidak akan memuatnya sama sekali
Saya akan berpikir begitu - secara logis, tampaknya masuk akal bahwa secara umum pengoptimal permintaan akan mengabaikannya.
6
Anda dapat membandingkan rencana eksekusi dengan dan tanpa1=1
Luc M
4
@ Luc M: Saya melakukan itu untuk SQLite. Ternyata itu tidak mengoptimalkan WHILE 1=1klausa. Namun, tampaknya tidak memiliki dampak yang terdeteksi pada waktu eksekusi.
dan04

Jawaban:

23

Semua RDBMS utama, sejauh yang saya tahu, telah dibangun dalam evaluasi konstan. Ini harus mengevaluasi hampir seketika di salah satu dari mereka.

JNK
sumber
+1 Ini dugaan saya juga, tapi alasan saya mengajukan pertanyaan adalah untuk mendapatkan sedikit lebih detail. Saya akan tetap buka sedikit lebih lama untuk melihat apakah saya mendapat masukan lagi.
transistor1
2
Ini diabaikan. Ini tidak ada hubungannya dengan optimizer, hanya concat dari mana kondisi sesuai tautan yang bersangkutan (jawaban saya juga)
gbn
8

Dari Perspektif SQL Server jika Anda melakukan WHERE 1=1untuk memungkinkan untuk lulus parameter dinamis dan melewatkan parameter dari dievaluasi, saya sarankan Anda membaca beberapa artikel dari SQL Server MV Erland Sommarskog. Pendekatannya menghilangkan kebutuhan untuk melakukan beberapa trik lain di dalam SQL dinamis (seperti WHERE Column = Columnkonstruk atau menggunakan WHERE (Col = Val OR 1=1) and (Col2 = Val2 OR 1=1)konstruk). The 1 = 1 seharusnya tidak menyebabkan masalah kinerja seperti yang disebutkan @JNK (Saya telah memberi 1 jawabannya di sana dan itu yang harus diterima), saya pikir Anda akan menemukan beberapa tips yang baik dari artikel Erland di sekitar SQL dinamis dan Anda juga akan melihat dia masih menggunakan yang 1=1untuk kasus-kasus di mana tidak ada parameter yang dilewati tetapi ia menghindarinya untuk parameter individu yang tidak dilewati, ia tidak melakukannya.

Mike Walsh
sumber
Aku hanya browsing artikel kedua (karena aku tidak menulis kode untuk 2008 SP1 pada saat ini), tapi saya melihat dia adalah menggunakan 1 = 1 di kode nya. Saya sudah terbiasa dengan sp_executesql, tapi itu tidak menghilangkan dorongan untuk menggunakan 1 = 1, dengan sendirinya. Mungkin saya melewatkan sesuatu?
transistor1
2
+1 - Erland adalah sumber daya masuk untuk hal semacam ini.
JNK
Hanya dengan mengutip dari tautan kedua: "Pada baris 19-29, saya menulis string SQL dasar. Syaratnya WHERE 1 = 1 pada baris 29 ada untuk memungkinkan pengguna memanggil prosedur tanpa menentukan parameter apa pun."
transistor1
2
Maaf. Saya salah mengetik poin saya. Akan diedit. Saya tidak bermaksud mengatakan bahwa ada masalah dengan konstruk Di mana 1 = 1, hanya menyarankan kiat lain untuk mudah dibaca dan mudah-mudahan menghindari melakukan pendekatan WHERE (kolom = nilai atau 1 = 1) dan (kolom1 = nilai1 atau 1 = 1), dll. Pendekatan.
Mike Walsh
6

Dengan MySQL, Anda dapat memeriksa, menjalankan MENJELAJAH DIPERPANJANG dan kemudian MENUNJUKKAN PERINGATAN untuk melihat permintaan yang sebenarnya. tl; dr: itu dioptimalkan jauh.

mysql> use test
Database changed
mysql> create table test1(val int);
Query OK, 0 rows affected (0.19 sec)

mysql> explain extended select * from test1 where val > 11 and 1 = 1;
+----+-------------+-------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | test1 | ALL  | NULL          | NULL | NULL    | NULL |    1 |   100.00 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

mysql> show warnings;
+-------+------+--------------------------------------------------------------------------------------------+
| Level | Code | Message                                                                                    |
+-------+------+--------------------------------------------------------------------------------------------+
| Note  | 1003 | select `test`.`test1`.`val` AS `val` from `test`.`test1` where (`test`.`test1`.`val` > 11) |
+-------+------+--------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)
Dalibor Karlovic
sumber
1
Jawaban yang bagus Btw MySQL server v5.7.18 mengatakan 'DIPERPANJANGKAN' sudah usang dan akan dihapus dalam rilis mendatang. Dari mysql doc: In older MySQL releases, extended information was produced using EXPLAIN EXTENDED. That syntax is still recognized for backward compatibility but extended output is now enabled by default, so the EXTENDED keyword is superfluous and deprecated. Its use results in a warning, and it will be removed from EXPLAIN syntax in a future MySQL release.Itu dihapus di MySQL v 8.0.
mikep