2009-09-09 21 views
6

ATM Próbuję się nauczyć, jak efektywnie korzystać z inwentarzu bazy danych i byłbym wdzięczny za zdobycie wiedzy eksperckiej. Obecnie nie mam żadnych problemów z wydajnością. Chciałbym tylko wiedzieć, w jaki sposób obsługiwać indeksy z tego zapytania:Jak przyspieszyć to zapytanie?

SELECT B.event, 
     COALESCE(B.system, C.surname || ' ' || C.forename) AS name, 
     C.label, 
     B.timestamp 
FROM A    
    INNER JOIN B ON A.event=B.event 
    INNER JOIN C ON B.state=C.id 
    LEFT OUTER JOIN D ON B.hur=D.id    
WHERE A.id IN(12,13,14,15,...) 
    ORDER BY B.event, B.timestamp 

A.id, C.id i D.id są już klucze podstawowe

UPDATE normalnie chciałbym umieścić INDEX (A.event) i INDEX (B.event, B.timestamp). Czy to jest poprawne? A co z B.event, B.state i B.hur?

+0

Prawidłowo, ale sprawdź, czy w rzeczywistości użyty zostanie B.timestamp. – Pomyk

+0

Jak duże są poszczególne tabele i ile wierszy będzie pasować do danego zapytania. Z której bazy danych korzystasz? –

+0

Ponadto, jak często dane są dodawane do tabel i jak często ma być uruchamiane zapytanie? –

Odpowiedz

3

Przepisz zapytanie jak to:

SELECT B.event, 
     COALESCE(B.system, C.surname || ' ' || C.forename) AS name, 
     C.label, 
     B.timestamp 
FROM B    
INNER JOIN 
     C 
ON  C.id = B.state 
LEFT OUTER JOIN 
     D 
ON  D.id = B.hur 
WHERE B.event IN 
     (
     SELECT event 
     FROM A 
     WHERE A.id IN (12, 13, 14, 15) 
     ) 
ORDER BY 
     B.event, B.timestamp 

i utworzyć kompozytowy indeks B (event, timestamp)

2

Można dodawać indeksy do wszystkiego w klauzulach WHERE i ORDER BY. Tj. A.Event, B.event i B.timestamp.

+1

Nie dodawaj indeksów ślepo. Zobacz odpowiedź Lieven. Dodanie indeksów na ślepo może zaszkodzić wydajności, ponieważ każdy indeks musi zostać utrzymany. W niektórych przypadkach, takich jak małe stoły, będzie to bolało, ponieważ IO używane do konserwacji może być używane gdzie indziej. Czasami pełne skanowanie tabeli na małym stole jest lepsze niż indeksy. – jim

+0

Kusi mnie, aby usunąć moją odpowiedź; jednak komentarz Jima jest przydatny, więc czy odpowiedź powinna pozostać? – darasd

0
SELECT B.event, B.system, COALESCE(C.surname) || ' ' || COALESCE(C.forename) AS name, C.label, B.timestamp 
FROM A    
INNER JOIN B ON A.event=B.event 
INNER JOIN C ON B.state=C.id 
LEFT OUTER JOIN D ON B.hur=D.id    
WHERE A.event = ANY(:visits) 
ORDER BY B.event, B.timestamp 

Również ORDER BY spowolni sprawy źle. Upewnij te są indeksowane:

A.event 
B.event 
B.state 
C.id 
B.timestamp 
3

ja zazwyczaj bierze kroki, gdy próbuje przyspieszyć moje zapytania

  1. analizować plan wykonania.
  2. Spróbuj utworzyć (obejmujące) indeksy, aby wyeliminować skanowanie tabeli.
  3. Spróbuj utworzyć (obejmujące) indeksy, aby wyeliminować skany indeksu.

Jak dla kwerendy, nie byłoby pomylić z tworzeniem indeksów na

  • A.event
  • B.event
  • B.state
  • B.Hur
+0

Tworzenie oddzielnych indeksów dla B.event i B.state nie jest tym samym, co tworzenie indeksu na (B.event, B.state). Ważne jest, aby to odróżnić, ponieważ ma bezpośredni wpływ na wydajność. – MatBailie

+0

@Dems: jeśli to pozostało niejasne w mojej odpowiedzi, masz rację. –

1

Dodałbym indeksy do wszystkiego, co jest połączone, w klauzuli where lub w klauzuli order by.

W takim przypadku dodać indeksy następujące (przy założeniu, że pola ID, to klucze główne i już indeksowane):

  1. A.event
  2. B.event
  3. B.state
  4. B. Hura
  5. B.event, B.timestamp (połączone wskaźnik obu polach)

Piąty, będący kombinacją wskaźników, powinien przyspieszyć zamówienie o.

Musisz hartować liczbę indeksów, niezależnie od spadku wydajności podczas wstawiania rekordów do tabeli (im więcej indeksów dodasz do tabeli, tym wolniejsze wstawki i aktualizacje będą aktualizowane, ponieważ indeksy wymagają aktualizacji) .

2

Ważne jest, aby pamiętać, że kolejność pól w indeksie jest ważne.

Indeks jest w pewnym sensie drzewem wyszukiwania. Jeśli indeksujesz (B.event, B.state), drzewo zgrupuje wszystkie rekordy z polem "zdarzenie" zapisu, a następnie uporządkuje je według pola "stan".

Gdybyś wtedy zapytał ten indeks o "b.state = x", indeks byłby mało przydatny; Indeks jest uporządkowany najpierw przez "wydarzenie".


W przykładzie:
- filtr A przez to jest "zdarzenie" field
- dołącz A.event do B.event
- dołącz B.state do C.id
- Dołącz B.hur = D.id
- Zamówienie przez B.event, B.timestamp

ważne jest, aby pamiętać, że optymalizacja będzie patrzeć na statystyki tabel i indeksów, a następnie może ponownie zmienić kolejność połączenia. Wynik będzie taki sam, ale kolejność może dać inną wydajność, a zadaniem optymalizatora jest próba znalezienia najlepszej wydajności.

W twoim przypadku oczekiwałbym, że zamówienie B.event będzie niezwykle ważne. Po prostu dlatego, że jest to kolejność wynikowego wyniku, I to jest pole, przez które filtrujesz.

Następnie dołączasz B.state do C.id. Zatem posiadanie i indeksowanie na C.id jest dobre, dzięki czemu łączenie jest szybsze. Ale równie dobrze posiadanie danych tabeli B w ładnej kolejności może również przyspieszyć połączenie.

Ale posiadanie indeksu na B.event i osobnego indeksu na B. stan może dać niewiele. Indeks B.state staje się obok bezcelowy, ponieważ używamy indeksu B.event. Jeśli połączysz te dwa w jeden indeks (b.event, a następnie b.state), plan wykonania może znaleźć sposób na użycie części b.state indeksu.

Ostatecznie, jeśli umieścisz wszystkie pola w indeksie, indeks się zwiększy, ale zapytanie może nigdy nie zajrzeć do tabeli. Informacje znajdują się w indeksie. Czas potrzebny do przejścia z indeksu do tabeli w celu znalezienia "brakujących" pól jest podobny do czasu łączenia. Tak więc dla wydajności odczytu, dodanie dodatkowych pól do indeksu może być znaczące.

mam Wittering na teraz, ale podsumowanie jest takie:
- Zwykle oddzielny indeks na oddzielnych pól nie przyzwyczaić razem
- Dla indeksów kompozytowych, kolejność określić pola robi różnicę
- Dodanie "dodatkowych" pól do indeksu powoduje, że jest on większy, ale może również przyspieszyć zapytania.
- Kolejność planu wykonania ma większe znaczenie niż kolejność zapytań.
- Ale posiadane indeksy mogą określać kolejność plan wykonania:

Ten rodzaj pracy ma brak kategorycznych odpowiedzi. To zależy od twoich danych, jest bliższe sztuce.

Jedną opcją jest przeciążenie tabel indeksami, sprawdzenie wynikowego planu wykonania i usunięcie indeksów, które nie są potrzebne.

Ale nawet tam obowiązuje zastrzeżenie. Ponieważ plan wykonania jest zależny od danych (i statystyk tabel), bardzo ważne jest, aby dane rzeczywiste w tabelach były prawdziwe. Podczas gdy tabele mają 10 lub 100 wierszy, jeden plan wykonania może być najszybszy. Ale gdy otrzymasz miliony wierszy, plan wykonania może się zmienić, a więc korzystać z różnych indeksów.

2

Przeprowadź objaśnienie analizy zapytania i przeczytaj - jeśli to nie pomoże - umieść dane wyjściowe analizy wyjaśniania na explain.depesz.com i sprawdź, co "mówi".

Powiązane problemy