Намерих решение, което разчита на свойствата на данните в таблицата. Бих предпочел по-общо решение, което не зависи от текущите данни, но за момента това е най-доброто, с което разполагам.
Проблемът с оригиналната заявка:
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 пъти по-бързо .