Znalazłem rozwiązanie, które opiera się na właściwościach danych w tabeli. Wolałbym mieć bardziej ogólne rozwiązanie, które nie zależy od bieżących danych, ale na razie jest to najlepsze, jakie mam.
Problem z pierwotnym zapytaniem:
SELECT P, Y, Z FROM SomeTable WHERE FirstX <= ? AND LastX >= ? LIMIT 10;
jest to, że wykonanie może wymagać przeskanowania dużego procentu wpisów w FirstX
,LastX
,P
indeks, gdy pierwszy warunek FirstX <= ?
spełnia duży procent wierszy.
Aby skrócić czas wykonania, zauważyłem, że LastX-FirstX
jest stosunkowo mały.
Uruchomiłem zapytanie:
SELECT MAX(LastX-FirstX) FROM SomeTable;
i otrzymałem 4200000
.
Oznacza to, że FirstX >= LastX – 4200000
dla wszystkich wierszy w tabeli.
Więc aby spełnić LastX >= ?
, musimy również spełnić FirstX >= ? – 4200000
.
Możemy więc dodać warunek do zapytania w następujący sposób:
SELECT P, Y, Z FROM SomeTable WHERE FirstX <= ? AND FirstX >= ? - 4200000 AND LastX >= ? LIMIT 10;
W przykładzie, który testowałem w pytaniu, liczba przetworzonych wpisów indeksu została zmniejszona z 2104820
do 18
a czas działania został skrócony z 0,563 sekundy do 0,0003 sekundy .
Przetestowałem nowe zapytanie z tym samym 120000
wartości X
. Dane wyjściowe były identyczne ze starym zapytaniem. Czas spadł z ponad 10 godzin do 5,5 minuty , który jest ponad 100 razy szybszy .