Jak sugeruje tytuł ... Próbuję znaleźć najszybszy sposób przy jak najmniejszym narzucie, aby określić, czy rekord istnieje w tabeli, czy nie.
Przykładowe zapytanie:
SELECT COUNT(*) FROM products WHERE products.id = ?;
vs
SELECT COUNT(products.id) FROM products WHERE products.id = ?;
vs
SELECT products.id FROM products WHERE products.id = ?;
Powiedzmy, że ?
jest zamienione na 'TB100'
... zarówno pierwsze, jak i drugie zapytanie zwróci dokładnie ten sam wynik (powiedzmy ... 1
dla tej rozmowy). Ostatnie zapytanie zwróci 'TB100'
zgodnie z oczekiwaniami lub nic, jeśli id
nie ma w tabeli.
Celem jest ustalenie, czy id
jest w tabeli, czy nie. Jeśli nie, program następnie wstawi rekord, jeśli tak, program go pominie lub wykona zapytanie UPDATE w oparciu o inną logikę programu spoza zakresu tego pytania.
Który jest szybszy i mniejszy? (Będzie to powtarzane dziesiątki tysięcy razy podczas każdego uruchomienia programu i będzie uruchamiane wiele razy dziennie).
(Uruchamianie tego zapytania względem M $ SQL Server z Java za pośrednictwem sterownika JDBC dostarczonego przez M $)
źródło
if exists(select null from products where id = @id)
; jeśli w zapytaniu wywoływanym bezpośrednio przez klientaselect case when exists (...) then 1 else 0 end
.Odpowiedzi:
SELECT TOP 1 products.id FROM products WHERE products.id = ?;
osiągnie lepsze wyniki niż wszystkie Twoje sugestie, ponieważ zakończy wykonywanie po znalezieniu pierwszego rekordu.źródło
id
nie jest PK. Więc +1 do twojej rady.EXISTS
(lubNOT EXISTS
) jest specjalnie zaprojektowany do sprawdzania, czy coś istnieje i dlatego powinien być (i jest) najlepszą opcją. Zatrzyma się w pierwszym wierszu, który pasuje, więc nie wymagaTOP
klauzuli i w rzeczywistości nie wybiera żadnych danych, więc nie ma narzutu związanego z rozmiarem kolumn. Możesz bezpiecznie użyćSELECT *
tutaj - nie różni się odSELECT 1
,SELECT NULL
lubSELECT AnyColumn
... (możesz nawet użyć niepoprawnego wyrażenia, takiego jakSELECT 1/0
i nie zepsuje się) .źródło
Exists
działaselect
w taki sposób, że kończy pracę, gdy tylko zostanie znaleziony jeden wiersz. Ponadto istnieje po prostu odnotowuje istnienie rekordu, a nie rzeczywiste wartości w rekordzie, oszczędzając potrzebę ładowania wiersza z dysku (oczywiście zakładając, że kryteria wyszukiwania są indeksowane). Jeśli chodzi o koszty ogólneif
- i tak będziesz musiał spędzić ten malutki czas.select top
lubexists
; jeśli ich nie ma, silnik sql będzie musiał wykonać skanowanie tabeli. Jest to najmniej pożądana opcja wyszukiwania tabeli. Jeśli nie masz uprawnień do tworzenia indeksów, będziesz musiał skontaktować się z personelem technicznym po drugiej stronie, aby dowiedzieć się, czy dostosowują je automatycznie, czy też oczekują, że zasugerujesz indeksy.SELECT CASE WHEN EXISTS(..) THEN 1 ELSE 0 END;
Nic nie może pokonać -
Nie musisz liczyć, aby wiedzieć, czy w tabeli znajdują się dane. I nie używaj aliasu, gdy nie jest to konieczne.
źródło
id
nie ma klucza podstawowego. Tak więc, nawet jeśli nie liczysz , nadal musisz znaleźć wszystkie pasujące rekordy, być może tysiące z nich. O aliasowaniu - kod jest ciągle w toku. Nigdy nie wiesz, kiedy będziesz musiał wrócić. Aliasing pomaga zapobiegać głupim błędom w czasie wykonywania; na przykład unikalna nazwa kolumny, która nie wymagała aliasu, nie jest już unikalna, ponieważ ktoś utworzył kolumnę o tej samej nazwie w innej, połączonej tabeli.aliasing
. Poprawny termin toqualifying
. Oto dłuższe wyjaśnienie Alexa Kuznetzova . O zapytaniami jednej tabeli - jest to pojedynczy stół teraz . Ale później, gdy zostanie wykryty błąd i próbujesz powstrzymać powódź, klient jest zdenerwowany, dołączasz do innego stołu tylko po to, aby zmierzyć się z komunikatem o błędzie - łatwo korygowanym komunikatem, ale nie w tym spoconym momencie, uderza mały skok - i poprawiasz błąd zapamiętywania, że nigdy nie opuszczałem kolumny ...To podejście zwraca dla Ciebie wartość logiczną.
źródło
Możesz także użyć
źródło
Nie myśl, że ktoś jeszcze o tym wspomniał, ale jeśli masz pewność, że dane pod tobą się nie zmienią, możesz również zastosować wskazówkę NoLock, aby upewnić się, że nie jest blokowana podczas czytania.
źródło
Jest to rozwiązanie obejmujące wiele relacyjnych baz danych, które działa we wszystkich bazach danych.
źródło
Poniżej znajduje się najprostszy i najszybszy sposób określenia, czy rekord istnieje w bazie danych, czy nie. Dobrze, że działa we wszystkich relacyjnych bazach danych
źródło
źródło
Używałem tego w przeszłości i nie wymaga pełnego skanowania tabeli, aby sprawdzić, czy coś istnieje. Jest super szybki ...
źródło
Dla tych, którzy natkną się na to w tle MySQL lub Oracle - MySQL obsługuje klauzulę LIMIT, aby wybrać ograniczoną liczbę rekordów, podczas gdy Oracle używa ROWNUM.
źródło