2010-07-28 12 views
8

Utrata niektórych problemów dotyczących wydajności bazy danych w dość typowej aplikacji EclipseLink/JPA.W jakich warunkach SELECT by PRIMARY KEY był powolny?

Widzę częste zapytania, które pobierają 25-100ms. Są to proste zapytania, po prostu wybieranie wszystkich kolumn z tabeli, w której klucz podstawowy jest równy wartości. Nie powinny być powolne.

Patrzę na czas kwerendy w dzienniku PostgreSQL, używając log_min_duration_statement, więc powinno to wyeliminować obciążenie sieci lub aplikacji.

To zapytanie nie jest wolne, ale jest używane bardzo często.

Dlaczego wybór * według klucza podstawowego był powolny? Czy jest to specyficzne dla PostgreSQL czy jest to ogólny błąd DB? Jak mogę to przyspieszyć? Ogólnie? Dla postgres?

zapytania próbki z dziennika pg:

2010-07-28 08:19:08 PDT - LOG: duration: 61.405 ms statement: EXECUTE <unnamed> [PREPARE: SELECT coded_ele 
ment_key, code_system, code_system_label, description, label, code, concept_key, alternate_code_key FROM coded 
_element WHERE (coded_element_key = $1)] 

Tabela ma około 3,5 miliona wierszy.

Uruchomiłem również EXPLAIN i EXPLAIN ANALYSE dla tego zapytania, a jego jedynym zadaniem jest skanowanie indeksu.

+0

Jak duży jest zestaw danych? Jak duży jest każdy rząd? Jak wygląda zapytanie? –

+0

Czy zgrupowałeś swoją bazę danych? Czy przed wysłaniem robisz pełną analizę próżni? A jaka jest wersja Pg? – jmz

+0

Brak klastrów, tak naprawdę nie jest to opcja. Nie zrobiłem jeszcze pełnej analizy próżni (będę), a to jest PG 8.1. – Freiheit

Odpowiedz

4

Wybierz * powoduje, że twoja baza danych pracuje ciężej i co do zasady jest złą praktyką. Istnieje mnóstwo pytań/odpowiedzi na temat stackoverflow, mówiąc o tym.

Czy próbowałeś zastąpić * nazwami pól?

+1

JPA generuje zapytania, jak opisujesz przy pomocy nazw pól. Opisałem to jako "Wybierz *" dla zwięzłości. – Freiheit

+0

Ah - nie zasłużyłeś na to wtedy :-) Jest milion innych rzeczy, które mogą wpływać na permrmance ... tabele kompaktowania lub przebudowywanie indeksów może pomóc, ustawiając dopełnienie indeksu bardziej przyjazne dla czytania niż pisanie, partycjonowanie (czy to na wolniejszym dysku), kolumny obliczane, zmieniające kolejność pól w SELECT (dlaczego nadal nie wiem) itp. – dave

+0

Zaakceptowane głównie w celu dodania komentarza, a nie początkowej odpowiedzi. Dał mi listę rzeczy do zrozumienia i zbadania, aby przyspieszyć zapytanie. – Freiheit

2

Czy możesz uzyskać pewien rodzaj sprzeciwu blokowania? Jakie rodzaje zamków bierzesz podczas wykonywania tych zapytań?

+0

Nie jestem pewien. Czy jest jakiś sposób, aby PG lub WZP poinformowały mnie o wydaniu blokady? – Freiheit

2

Cóż, nie wiem zbyt wiele na temat PostgreSQL, więc dam ci wskazówkę do MS SQL Server, która może mieć zastosowanie.

Serwer MS SQL Server ma pojęcie "wskaźnika klastra", który jest fizycznym układem danych na dysku. Dobrze jest używać na polu, w którym będziesz szukał zakresu pomiędzy wartościami (głównie pola daty). Nie jest to przydatne, jeśli szukasz dokładnej wartości (takiej jak wyszukiwanie klucza podstawowego). Czasami jednak główny indeks klucza jest nieumyślnie ustawiony jako indeks klastrowy. Spowoduje to odszukiwanie indeksu do skanowania tabeli.

+0

W jaki sposób za pomocą indeksu klastrowanego dla klucza podstawowego włączyć wyszukiwanie indeksu klucza podstawowego do skanowania tabeli? –

+0

Ponieważ tabela jest indeksem. W związku z tym "Skanowanie indeksu" == "Skanowanie tabeli" –

+0

Ale wyszukiwanie indeksu nie będzie skanowaniem indeksu, chyba że mam sparaliżowaną terminologię. –

1

select * jest prawie zawsze bardzo złym pomysłem.

  1. Jeśli kolejność pól się zmieni, spowoduje to złamanie kodu. Zgodnie z komentarzami, nie jest to ważne, biorąc pod uwagę bibliotekę abstrakcji, której używasz.
  2. Prawdopodobnie zwracasz więcej danych ze stołu niż faktycznie chcesz. Wybranie dla określonych pól, które chcesz, może zaoszczędzić czas transferu.

25ms to mniej więcej granica, którą zobaczysz na prawie każdym zapytaniu SQL - to tylko dwa dostępy do dysków! Możesz zastanowić się, jak zmniejszyć liczbę uruchomień zapytania, a nie próbować zoptymalizować zapytanie.

+0

Naprawdę żałuję, że ludzie nie zirytują KOMENTARZ, kiedy przegłosują! –

+1

@Billy, nie masz racji na dwóch kontach: 1. Kolejność pól nie ulega zmianie, chyba że upuścisz tabelę. 25ms dla PK to bardzo długi czas. Jednak nie było to przyczyną. Nie odpowiedziałeś na pytanie, w jaki sposób rozwiązać problem, a nie na liczbę losowych dostępów do dysków w ciągu 25 ms. – jmz

+0

@jmz: ALTER może również zmieniać kolejność pól. Jeśli chodzi o pytanie, uważam, że brzmiało "Dlaczego wybór * według klucza podstawowego był powolny?", A następnie "Jak mogę to przyspieszyć?", W którym to przypadku nie widzę, jak to nie odpowiada na pytanie. –

1

Wiersz wyjątkowo duży lub zawierający BLOBy i duże pola binarne?

Czy jest to bezpośrednio przez konsolę, czy to zapytanie jest uruchamiane przez niektóre API dostępu do danych, takie jak jdbc lub ADO.NET? Wspominałeś o JPA, który wygląda jak API dostępu do danych. W przypadku krótkich zapytań interfejs dostępu do danych staje się większym procentem czasu wykonywania - tworzenie polecenia, tworzenie obiektów do przechowywania wierszy i komórek itp.

+0

Prędkości tych zapytań są rejestrowane z dzienników postgresu, więc jest to rzeczywisty czas zapytania, a nie czas interfejsu API danych (JPA). – Freiheit