Намерих решение, което разчита на свойствата на данните в таблицата. Бих предпочел по-общо решение, което не зависи от текущите данни, но за момента това е най-доброто, с което разполагам.
Проблемът с оригиналната заявка:
SELECT P, Y, Z FROM SomeTable WHERE FirstX <= ? AND LastX >= ? LIMIT 10;
е, че изпълнението може да изисква сканиране на голям процент от записите в FirstX
,LastX
,P
индекс, когато първото условие FirstX <= ?
е удовлетворен от голям процент от редовете.
Това, което направих, за да намаля времето за изпълнение, е да наблюдавам, че LastX-FirstX
е относително малък.
Пуснах заявката:
SELECT MAX(LastX-FirstX) FROM SomeTable;
и получи 4200000
.
Това означава, че FirstX >= LastX – 4200000
за всички редове в таблицата.
Така че, за да удовлетворите LastX >= ?
, трябва също да удовлетворим FirstX >= ? – 4200000
.
Така че можем да добавим условие към заявката, както следва:
SELECT P, Y, Z FROM SomeTable WHERE FirstX <= ? AND FirstX >= ? - 4200000 AND LastX >= ? LIMIT 10;
В примера, който тествах във въпроса, броят на обработените индексни записи беше намален от 2104820
до 18
и времето за работа беше намалено от 0,563 секунди до 0,0003 секунди .
Тествах новата заявка със същите 120000
стойности на X
. Резултатът беше идентичен със старата заявка. Времето намаля от над 10 часа до 5,5 минути , което е над 100 пъти по-бързо .