Optymalizacja zapytania - czy coś przyśpieszy

0

Mam tabelę elementów z kluczem głównym "id" zawierającą miedzy innymi indeksowaną kolumnę kategorii "category" po której chcę wyszukiwać elementy. Wiem że pewne typy kategorii mogą występować tylko w pewnych przedziałach "id". Czy dodanie tego warunku do "selecta" przyspieszy wyszukiwanie np.

SELECT * FROM tab_1 WHERE category='kat_1' AND id < 1000;

?

0

Zależy od tego co SZBD postanowi, ale na 99% będzie szybsze.

0

jeśli masz indeks na kolumnie category i osobny na kolumnie id to na 99% nie będzie szybciej. Jeśli optymalizator zdecyduje się użyć indeksu na polu id to będzie zapewne wolniej, jeśli na polu category to tak samo. BTW nie prościej sprawdzić plan zapytania dla obu przypadków??

0

@abrakadaber o_O? Umyka mi chyba twoja logika, bo to co napisałes nie ma sensu.
Rozumiesz chyba że SZBD użyje obu indeksów zapewne? Następnie zrobi przecięcie tych dwóch zbiorów ze wskaźnikami do interesujących go indeksów i na koniec zrobi odczyt danych z bazy. Nawet gdyby tak nie było i użyty byłby tylko indeks na id to dodanie selekcji po ID które jest kluczem głównym tabeli -> jest kluczem typu primary i jednocześnie sparse co oznacza że SZBD może bardzo szybko wyliczyć ile danych musi pobrać a potem może łyknąć te dane w jednym rzucie bo są przecież ułożone w odpowiedniej kolejności (można zrobić read-ahead dla indeksu primary).
Tak czy siak będzie to dużo szybsze niż wybieranie z indeksu category bo to indeks secondary i dense więc nie dość że samo wybranie wskaźników do rekordów będzie dłuższe to jeszcze na koniec SZBD będzie musiał dokonać wielu odczytów z dysku ;]

0

odpal sobie jakiekolwiek zapytanie aby pokazało Ci plan - jak znajdziesz taki SZBD, który do wybrania danych z tabeli użyje więcej niż jednego zapytania to jesteś gość. Jeśli chodzi o mysql to PK na tabeli InnoDB jest sparse.
BTW co to za skrót OSZBD bo chyba nie Object SZBD bo tu mowa o mysqlu
BTW2 jak już gość ma tą tabelę i te dane to co mu szkodzi po prostu sprawdzić?
BDW3 ja tam zazwyczaj bazy mam na maszynach, gdzie spokojnie cała się w RAMie zmieści (fakt, że to małe bazy są bo rzędu dziesiąt - set GB)

0

Z tym skrótem oczywiście chodziło o SZBD ;)

  1. Na pewno nie użyje więcej niz jednego ZAPYTANIA, ale jak najbardziej użyje więcej niż jednego INDEKSU żeby ograniczyć liczbę odczytów z dysku. Zostaną wybrane zbiory wskaźników do rekordów na podstawie indeksów a potem te zbiory zostaną przecięte.
  2. Tylko indeksy primary mogą być sparse ;]
  3. Sprawdzić zawsze można ;)
  4. To jest wtedy trochę inna bajka jak masz bazę w pamięci ;)
0
  1. Na pewno nie użyje więcej niz jednego ZAPYTANIA, ale jak najbardziej użyje więcej niż jednego INDEKSU żeby ograniczyć liczbę odczytów z dysku. Zostaną wybrane zbiory wskaźników do rekordów na podstawie indeksów a potem te zbiory zostaną przecięte.

No ok, ale dlaczego to miałoby cokolwiek przyspieszyć?
Jeżeli zakładamy, że wszystkie rekordy o tej kategorii mają id<1000, to po wybraniu rekordów po kategorii (na podstawie indeksu) dodatkowe warunek na id nie zmniejszy zbioru, który trzeba będzie odczytać z tabeli.

Dodanie tego warunku na id ma sens tylko, gdy zachodzi jedno z:

  1. Tabela ma partycje po kolumnie id i rekordy z id<1000 są w jednej partycji
  2. Optymalizator dojdzie do wniosku, że korzystanie z indeksu po kategorii nie ma sensu i zrobić scan tych 1000 elementów bezpośrednio z tabeli (aby uniknąć odczytu indeksu i później key lookapów).
0

Może być szybciej, może być wolniej a może być tak samo. Korelacja wartości w jednej kolumnie z wartościami w innej kolumnie to świetny sposób na zmylenie optymalizatora. Nie znam optymalizatora, który potrafiłby sobie z takimi korelacjami sensownie poradzić - najczęściej zakłada się całkowitą niezależność kolumn. W efekcie dołożenie takiego warunku może pogorszyć sytuację, jeśli SZBD zdecyduje się wybierać po dwóch kolumnach z dwóch indeksów i policzyć przecięcie zbiorów licząc na redukcję liczby rekordów, gdy tymczasem takowej redukcji wcale nie będzie.

0

@Tintin - Twoje pytanie jest bardzo ogólne i dotyka zarówno tematu wyboru optymalnego planu jak i samej konstrukcji indeksów.

W SQL Server - zastosowałbym taki dodatkowy warunek i jestem pewien, że mając tabelę z indeksem klastrowym na ID oraz nieklastrowym na Category, wyciągając dane tak jak Ty (wszystkie kolumny Select *), wydajność byłaby lepsza.

To też zależy jaki masz rozkład danych w tabeli i od kilku innych jeszcze czynników. W SQL Server wolniej na pewno by niebyło :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1