Trzy stoły:
product
: z kolumnami: ( a, g, ...a_lot_more... )
a: PK, clustered
g: bit-column
main
: z kolumnami: ( c, f, a, b, ...a_lot_more... )
c: PK, clustered
f: bit-column
(a, b): UQ
lookup
z kolumnami: ( a, b, c, i )
(a, b): PK, clustered
a: FK to product(a)
c: UQ, FK to main(c)
i: bit-column
Nie mogę znaleźć dobrych indeksów dla złączenia:
FROM
product
JOIN
lookup
ON lookup.a = product.a
JOIN
main
ON main.c = lookup.c
WHERE
product.g = 1
AND
main.f = 1
AND
lookup.i = 1
AND lookup.b = 17
Wypróbowałem indeks pokrycia product (g, a, ...)
i jest on używany, ale nie ze spektakularnymi wynikami.
Niektóre kombinacje indeksów w lookup
tabeli tworzą plany wykonania ze scalaniem indeksów, z niewielkim wzrostem wydajności w porównaniu z poprzednim planem.
Czy brakuje mi oczywistej kombinacji?
Czy ponowne zaprojektowanie konstrukcji może pomóc?
DBMS to MySQL 5.5, a wszystkie tabele używają InnoDB.
Rozmiary stołu:
product: 67K , g applied: 64K
main: 420K , f applied: 190K
lookup: 12M , b,i applied: 67K
mysql
mysql-5.5
optimization
ypercubeᵀᴹ
źródło
źródło
Odpowiedzi:
To mnie boli ...
Wcześniej musiałem używać tabel tymczasowych z InnoDB. Załaduj je z filtrami, utwórz indeks, dołącz do tabeli temp.
Problem, jak sądzę, polega na tym, że InnoDB ma tylko algorytm Nested Join: dorosłe optymalizatory zapytań RDBMS mają więcej do wykorzystania. Jest to oparte na próbie uruchomienia ładowań typu Data Warehouse na InnoDB.
Tabele temp zmniejszają ogólną złożoność w dół poziomu optymalizatora zapytań MySQL ...
źródło
main
) poprzez denormalizację danychlookup
?Wygląda jak produkt kartezjański. Powtórz kryteria DOŁĄCZ
SUGESTIA ALTERNATYWNA
Może się to wydawać niekonwencjonalne i prawdopodobnie pachnie jak SQL Anitpattern, ale oto idzie ...
Nie przesunąłem
product.g = 1
imain.f = 1
do podkwerend, ponieważ są to pola bitowe i po prostu wykonam skanowanie tabeli w tym momencie. Nawet gdyby pola bitowe były indeksami, Optymalizator zapytań po prostu zignorowałby taki indeks.Oczywiście możesz zmienić
SELECT * FROM lookup
na,SELECT a FROM lookup
jeśli twój SELECT nie potrzebuje niczegolookup
Być może włącz a, b do JOIN między wyszukiwaniem a głównym, jeśli ma to sens
lub odłóż c i połącz trzy kolumny (Indeks trzech kolumn w
main
ilookup
)źródło
main.f
iproduct.g
??? Jeśli liczebnośćmain.f
iproduct.g
dla wartości wynosi 1 jest mniejsza niż 5% wierszy tabeli, indeks namain.f
iproduct.g
może być uzasadniony.main.f
iproduct.g
wynosi 2, możesz porzucić te indeksy.