Biorąc pod uwagę to pytanie na reddit, wyczyściłem zapytanie, aby wskazać, gdzie problem był w zapytaniu. Najpierw używam przecinka, WHERE 1=1
aby ułatwić modyfikowanie zapytań, więc moje zapytania zwykle kończą się tak:
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
Ktoś w zasadzie powiedział, że 1 = 1 jest ogólnie leniwy i źle wpływa na wydajność .
Biorąc pod uwagę, że nie chcę „przedwcześnie optymalizować” - chcę przestrzegać dobrych praktyk. Wcześniej przeglądałem plany zapytań, ale ogólnie tylko po to, aby dowiedzieć się, jakie indeksy mogę dodać (lub dostosować), aby moje zapytania działały szybciej.
Pytanie naprawdę ... czy Where 1=1
powoduje złe rzeczy? A jeśli tak, jak mogę to stwierdzić?
Drobna edycja: Zawsze też „zakładałem”, 1=1
że zostanie zoptymalizowany, aw najgorszym razie będzie nieistotny. Nigdy nie boli kwestionować mantry, takiej jak „Goto's Evil” lub „Premature Optimization ...” lub inne domniemane fakty. Nie byłem pewien, czy 1=1 AND
realistycznie wpłynie to na plany zapytań, czy nie. A co z podkwerendami? CTE? Procedury?
Nie jestem osobą do optymalizacji, chyba że jest to potrzebne ... ale jeśli robię coś, co w rzeczywistości jest „złe”, chciałbym zminimalizować efekty lub zmienić w stosownych przypadkach.
źródło
Odpowiedzi:
SQL Server
parserOptymalizator ma funkcję o nazwie „Stałe składanie”, która eliminuje wyrażenia tautologiczne z zapytania.Jeśli spojrzysz na plan wykonania, nigdzie w predykatach nie zobaczysz tego wyrażenia. Oznacza to, że stałe składanie i tak jest wykonywane w czasie kompilacji z tego i innych powodów i nie ma wpływu na wydajność zapytań.
Aby uzyskać więcej informacji, zobacz Ciągłe składanie i ocena wyrażeń podczas szacowania liczności .
źródło
Dodanie nadmiarowego predykatu może mieć znaczenie w SQL Server.
W poniższych planach wykonania zwróć uwagę
@1
na pierwszy plan vs. literał'foo'
w drugim planie.Oznacza to, że SQL Server wziął pod uwagę pierwsze zapytanie w celu prostej parametryzacji celu promowania ponownego użycia planu wykonania - jednak porównanie dwóch stałych zapobiega temu w drugim przypadku.
Lista warunków, które uniemożliwiają prostą parametryzację (wcześniej znaną jako autoparametryzacja) można znaleźć w załączniku A do dokumentacji technicznej Microsoft Caching Plan:
prosta parametryzacja nie jest jednak czymś, na czym powinieneś polegać. Zdecydowanie lepiej jest sparametryzować swoje zapytania.
źródło
W każdym nowoczesnym RDBMS (w tym Oracle, Microsoft SQL Server i PostgreSQL - jestem tego pewien) nie będzie to miało wpływu na wydajność.
Jak ktoś zauważył, będzie to miało wpływ tylko na fazę planowania zapytań. Dlatego różnica będzie widoczna tylko wtedy, gdy uruchomisz tysiące iteracji uproszczonego zapytania, które nie zwraca żadnych danych, takich jak ten:
Dla mnie w PostgreSQL 9.0 jest to widoczne tylko przy 10000 iteracjach:
źródło
Może to stanowić „problem” dla Oracle, gdy używasz parametru bazy danych sharing_sharing. Ustawienie tej opcji na „wymuś” spowoduje zmodyfikowanie wszystkich instrukcji SQL. Wszystkie „stałe” w zapytaniach zostaną zastąpione zmiennymi powiązania (np. 1 =>: SYS_0).
Ta opcja została wprowadzona, aby poradzić sobie z niektórymi leniwymi programistami. Z drugiej strony może też zaszkodzić innym leniwym programistom. Ale ryzyko nie jest zbyt wysokie. Od 11g ma funkcję podglądu zmiennych.
źródło