Właśnie skonfigurowałem system rejestrowania, który składa się z wielu tabel o tym samym układzie.
Dla każdego źródła danych istnieje jedna tabela.
W przypadku przeglądarki dziennika chcę
- UNION wszystkie tabele dziennika ,
- filtruj je według konta ,
- dodaj pseudokolumnę do identyfikacji źródła,
- posortuj je według czasu ,
- i ogranicz je do stronicowania .
Wszystkie tabele zawierają pole o nazwie zeitpunkt
indeksowana kolumna daty / godziny.
Moja pierwsza próba to:
(SELECT l.id, l.account_id, l.vnum, l.count, l.preis, l.zeitpunkt AS zeit,
'hp' AS source FROM is_log AS l WHERE l.account_id = 730)
UNION
(SELECT l.id, l.account_id, l.vnum, l.count, l.preis, l.zeitpunkt,
'ig' AS source FROM ig_is_log AS l WHERE l.account_id = 730)
ORDER BY zeit DESC LIMIT 10;
Optymalizator nie może tutaj użyć indeksów, ponieważ wszystkie wiersze z obu tabel są zwracane przez podzapytania i sortowane po UNION
.
Moje obejście było następujące:
(SELECT l.id, l.account_id, l.vnum, l.count, l.preis, l.zeitpunkt AS zeit,
'hp' AS source FROM is_log AS l WHERE l.account_id = 730
ORDER BY l.zeitpunkt DESC LIMIT 10)
UNION
(SELECT l.id, l.account_id, l.vnum, l.count, l.preis, l.zeitpunkt,
'ig' AS source FROM ig_is_log AS l WHERE l.account_id = 730
ORDER BY l.zeitpunkt DESC LIMIT 10)
ORDER BY zeit DESC LIMIT 10;
Spodziewałem się, że silnik zapytań użyje tutaj indeksów, ponieważ oba podkwerendy powinny zostać posortowane i ograniczone już przed UNION
, który następnie łączy i sortuje wiersze.
Naprawdę myślałem, że to będzie to, ale uruchomienie EXPLAIN
zapytania powoduje, że podkwerendy wciąż przeszukują obie tabele.
EXPLAINing
same podkwerendy pokazują mi pożądaną optymalizację, ale UNIONing
razem ich nie robi.
Przegapiłem coś?
Wiem, że ORDER BY
klauzule w UNION
podzapytaniach są ignorowane bez znaku LIMIT
, ale jest pewien limit.
Edycja:
W rzeczywistości prawdopodobnie będą też zapytania bezaccount_id
warunku.
Tabele już istnieją i są wypełnione danymi. Mogą występować zmiany w układzie w zależności od źródła, dlatego chcę je podzielić. Ponadto klienci rejestrujący używają różnych poświadczeń z określonego powodu.
Muszę zachować rodzaj warstwy między czytnikami dzienników a rzeczywistymi tabelami.
Oto plany wykonania dla całego zapytania i pierwszego podzapytania, a także szczegółowo układ tabeli:
UNION DISTINCT
? Nie ma potrzeby wymuszania sortowania i rozróżniania tam, ponieważ wyniki będą różne dla podkwerend, ze względu na dodatkową kolumnę identyfikacyjną. Zastosowanie UNION ALL
.
source
kolumną? W ten sposób można uniknąć UNION
s i używać indeksów dla wszystkich danych.
UNION ALL
inny system daje inny plan wykonania.
(account_id, zeitpunkt)
. Czy masz taki indeks? Drugi najlepszy byłby (myślę) singiel(zeitpunkt)
- ale wydajność, jeśli zostanie użyta, zależy od tego, jak częstoaccount_id=730
pojawiają się wiersze .