Czy „WHERE 1 = 1” zwykle ma wpływ na wydajność zapytań?

19

Ostatnio widziałem pytanie „gdzie 1 = 1 zdanie” ; konstrukt SQL, którego często używałem przy konstruowaniu dynamicznego SQL, aby pisać czystszy kod (z perspektywy języka hosta).

Ogólnie rzecz biorąc, czy to dodanie do instrukcji SQL negatywnie wpływa na wydajność zapytań? Nie szukam odpowiedzi w odniesieniu do konkretnego systemu bazy danych (ponieważ użyłem jej w DB2, SQL Server, MS-Access i mysql) - chyba że nie można odpowiedzieć bez wchodzenia w szczegóły.

tranzystor 1
źródło
4
Wierzę, że każdy optymalizator będzie w stanie obsłużyć takiego warunku prosty i po prostu zignorować to więc ostateczny plan wykonanie nie byłoby zawiera go wcale
Też tak sądzę - logicznie rzecz biorąc, wydaje się sensowne, że optymalizator zapytań po prostu zignoruje to.
6
Możesz porównać plan egzekucji z i bez1=1
Luc M
4
@Luc M: Zrobiłem to tylko dla SQLite. Okazuje się, że nie optymalizuje WHILE 1=1klauzuli. Jednak nie wydaje się mieć żadnego wykrywalnego wpływu na czas wykonywania.
dan04,

Odpowiedzi:

23

O ile mi wiadomo, wszystkie główne RDBMS mają ciągłe oceny. Powinno to ocenić niemal natychmiast w dowolnym z nich.

JNK
źródło
+1 To też jest moje przypuszczenie, ale zadałem pytanie, aby uzyskać trochę więcej szczegółów. Pozostawię go dłużej otwarty, aby zobaczyć, czy otrzymam więcej informacji.
tranzystor1
2
To jest ignorowane. Z optymalizatorem nie ma nic innego, po prostu stwierdzenie, gdzie uwarunkowanie jest zgodne z pytaniem (moja odpowiedź)
gbn 16.11.11
8

Z perspektywy SQL Server, jeśli robisz to, WHERE 1=1aby umożliwić dynamiczne przekazywanie parametrów i pomijanie parametru podczas oceny, sugerowałbym przeczytanie kilku artykułów z SQL Server MV Erland Sommarskog. Jego podejście eliminuje potrzebę wykonywania innych sztuczek w dynamicznym SQL (takich jak WHERE Column = Columnkonstrukcja lub użycie WHERE (Col = Val OR 1=1) and (Col2 = Val2 OR 1=1)konstruktu). 1 = 1 nie powinien powodować problemów z wydajnością, jak wspomniał @JNK (dałem +1 jego odpowiedzi i to ta, którą należy zaakceptować), myślę, że znajdziesz kilka dobrych wskazówek z artykułu Erlanda na temat Dynamiczny SQL, a zobaczysz również, że nadal używa tego 1=1w przypadkach, gdy nie są przekazywane żadne parametry, ale unika ich dla poszczególnych parametrów, które nie są przekazywane, po prostu nie robi

Mike Walsh
źródło
Ja tylko przeglądanie drugi artykuł (bo nie piszę kod dla 2008 SP1 w tej chwili), ale widzę, że jest przy użyciu 1 = 1 w swoim kodzie. Znam już sp_executesql, ale to nie eliminuje konieczności użycia 1 = 1. Może coś mi umknęło?
tranzystor1
2
+1 - Erland to podstawowy zasób tego typu.
JNK
Cytując tylko z drugiego linku: „W wierszach 19–29 tworzę podstawowy ciąg SQL. Warunek, GDZIE 1 = 1 w wierszu 29, umożliwia użytkownikom wywołanie procedury bez podawania żadnych parametrów”.
tranzystor1
2
Przepraszam. Źle wpisałem swój punkt widzenia. Będzie edytować. Nie chciałem sugerować, że istnieje problem z konstrukcją Where 1 = 1, po prostu sugeruję inne wskazówki dla czytelności i mam nadzieję, że unikam podejścia WHERE (kolumna = wartość lub 1 = 1) i (kolumna1 = wartość1 lub 1 = 1) itp. Podejście.
Mike Walsh,
6

Za pomocą MySQL możesz sprawdzić, uruchamiając EXPLAIN EXTENDED, a później POKAŻ OSTRZEŻENIA, aby zobaczyć aktualne zapytanie. tl; dr: zostaje zoptymalizowany.

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 Karlović
źródło
1
Świetna odpowiedź. Serwer Btw MySQL w wersji 5.7.18 mówi, że „EXTENDED” jest przestarzały i zostanie usunięty w przyszłej wersji. Z 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.Został on usunięty w MySQL v 8.0.
mikep