Wydajność zapytania SQL cierpi gdy pytasz o zbyt wiele.
SELECT * powinno się unikać
Jest wiele powodów, dla których SELECT * źle wpływa na wydajność zapytania SQL a tym samym całego serwera SQL. Przede wszystkim Twoja aplikacja w rzeczywistości najczęściej nie potrzebuje wszystkich kolumn. Kiedy piszesz kod produkcyjny, wyraźnie określaj interesujące Cię kolumny, nie tylko ze względu na wydajność, ale także ze względu na niezawodność aplikacji. Na przykład nigdy nie możesz być pewny czy kod przetwarzania danych w Twojej aplikacji nagle się nie zepsuje po dodaniu nowej kolumny lub zmianie kolejności kolumn w tabeli. Korzystanie z SELECT * może odpowiadać za:
- zwiększony ruch sieciowy
- zwiększone użycie procesora po stronie klienta
- niemożność skorzystania z niektórych optymalizacji zapytań
- zwiększone wykorzystanie pamięci po stronie serwera
- zwiększone użycie procesora po stronie serwera
- zwiększoną ilość czasu potrzebną na analizowanie i optymalizację
Zobaczmy najważniejsze z nich.
Zwiększony ruch sieciowy
Jest to najbardziej oczywisty efekt - jeśli zwracasz 800 kolumn zamiast 8 kolumn z każdego wiersza, możesz skończyć z wysłaniem 100 razy większej ilości bajtów przez sieć przy każdym wykonaniu zapytania (oczywiście to może się różnić w zależności od długości poszczególnych kolumn). Więcej bajtów sieciowych oznacza więcej wysłanych pakietów sieciowych i, w zależności od implementacji RDBMS, także więcej informacji przesyłanych przez sieci na linii aplikacja – baza danych.
Przykładowo wybranie tylko 3 kolumn z 16 może dać ponad 2 razy krótszy czas odpowiedzi na zapytanie. A chodzi tu o całkowity czas potrzebny na wykonanie zapytania na serwerze bazy danych i pobranie wszystkich jego rekordów dla klienta, a więc opóźnienie sieci, przepustowość i konfiguracja bufora wysyłania TCP też będą miały na to wpływ.
Bazy Oracle mogą deduplikować powtarzające się wartości pól w zestawie wyników każdego wywołania pobierania. Jeśli więc chcesz pobrać wiele wierszy i kolumn oraz zaoszczędzić przepustowość sieci możesz zmaksymalizować taką „kompresję” poprzez uporządkowanie zestawu wyników zapytania według najbardziej powtarzalnych (najmniej odrębnych wartości) kolumn.
Zwiększone użycie procesora po stronie klienta
Im więcej wierszy przetwarzasz po stronie klienta i im więcej masz kolumn, tym więcej czasu procesora zajmie ich przetworzenie. W skrajnych przypadkach aplikacja może przez 99% swojego czasu zużywać bezsensownie procesor po stronie klienta, przetwarzając nadmiernie pobrane dane.
Sprawdź oferty pracy na TeamQuest
Oczywiście zysk na ograniczeniu zapytań może się różnić w zależności od rodzaju używanej aplikacji i używanych bibliotek klienta bazy danych. Niemniej jednak, gdy twoja tabela ma na przykład ponad 500 kolumn, różnica między zapytaniami SELECT *
i SELECT 10
może być ogromna.
Niemożność skorzystania z niektórych optymalizacji zapytań
Optymalizator Oracle może przekształcić strukturę Twojego zapytania w coś innego, ale logicznie równoważnego - jeśli tylko uzna, że jest to dobre dla wydajności. Niektóre transformacje otwierają dodatkowe możliwości optymalizacji (wydajniejsze ścieżki dostępu do danych), a niektóre pozwalają nawet na pominięcie wykonywania części zapytania. Na przykład, jeśli zdarzy się, że istnieje indeks obejmujący wszystkie kolumny wymagane przez SQL, Oracle może przeprowadzić skanowanie tylko indeksów. Chodzi tu o tzw. index full scan. który pozwala na szybkie i pełne skanowanie indeksu, jednocześnie bez przechodzenia po całym drzewie (ignorowanie bloków głównych i gałęzi).
Jeśli użyjesz SELECT *
to drastycznie zwiększasz szanse, że przynajmniej część kolumn objętych zapytaniem nie będzie zindeksowana a tym samym silnik bazy danych nie będzie mógł skorzystać z zaimplementowanej w nim optymalizacji.
Zobacz też popularne błędy w zapytaniach SQL.