Właściwie Twój klucz podstawowy nie ma większego sensu, jeśli chodzi o takie zapytanie o zakres. Wskazuje tylko unikalne pary dla <from_ip, to_ip>
krotka - w ten sposób MySQL nie będzie w stanie użyć tego indeksu z takimi porównaniami zakresów.
O ile nie uruchamiasz jakiegoś zapytania, które obejmuje obie części twojego klucza podstawowego, nie przyniesie ono żadnego efektu (cóż, właściwie MySQL również go użyje - gdy warunek wyboru używa lewy podzbiór indeksu złożonego , ale tak nie jest). Na przykład użyje klucza podstawowego:
-- @x and @y are derived from somewhere else
SELECT * FROM inetnum WHERE [email protected] && [email protected]
W twoim przypadku klucz złożony może być kluczem podstawowym, tak, ale jego jedyną korzyścią będzie zapewnienie unikalności. Możesz więc pozostawić to bez zmian lub utworzyć zastępczy id
klucz główny (zastępując obecny klucz główny przez UNIQUE
ograniczenie).
Jednym z możliwych rozwiązań poprawy sytuacji może być - utworzenie jednokolumnowych kluczy dla from_ip
i to_ip
. Ponieważ są to liczby całkowite, istnieje duża szansa na dużą kardynalność, jaką będą miały indeksy wynikowe. Jednak MySQL może używać tylko jednego indeksu, a zatem stracisz „połowę” efektywnego porównania zakresu. Należy również pamiętać, że jeśli porównanie większe (lub mniejsze niż) wpłynie na zbyt wiele wierszy, MySQL będzie nie używaj również indeksu (ponieważ oczywiście nie ma to sensu, ponieważ jest za dużo wierszy do zaznaczenia).
I - tak, unikaj używania funkcji w WHERE
klauzula. Nie mówię, że MySQL zawsze straci użycie indeksu w takim przypadku (ale najprawdopodobniej straci go w większości przypadków) - ale pomyśl o narzutu, który spowoduje wywołanie funkcji. Nawet jeśli jest niewielki - zawsze możesz się go pozbyć, przekazując poprawną wartość utworzoną przez twoją aplikację.