Различните стратегии за търсене имат смисъл за различни данни. По-специално, сканирането на индекс (като диапазон) често трябва да извършва търсене, за да прочете реда. В даден момент извършването на всички тези търсения е по-бавно, отколкото изобщо да не се използва индексът.
Вземете тривиален пример, таблица с три колони:id (първичен ключ), име (индексирано), рожден ден. Кажете, че има много данни. Ако помолите MySQL да търси рождения ден на Боб, той може да направи това доста бързо:първо, той намира Боб в индекса на името (това отнема няколко търсения, log(n), където n е броят на редовете), след това едно допълнително търсене за прочетете действителния ред във файла с данни и прочетете рождения ден от него. Това е много бързо и много по-бързо от сканирането на цялата таблица.
След това помислете за въвеждане на name like 'Z%'
. Това вероятно е доста малка част от таблицата. Така че е още по-бързо да намерите къде започват Zs в индекса на имената, след което за всеки от тях потърсете файла с данни, за да прочетете реда. (Това е сканиране на диапазон).
И накрая, помислете да поискате всички имена, започващи с M-Z. Това вероятно е около половината от данните. Може да направи сканиране на диапазон и след това много от търсения, но търсенето на случаен принцип върху файла с данни с крайната цел за четене на половината редове не е оптимално:би било по-бързо просто да извършите голямо последователно четене на файла с данни. Така че в този случай индексът ще бъде игнориран.
Това виждате — освен във вашия случай, има друг ключ, на който може да се обърне. (Възможно е също така действително да използва индекса на датата, ако не е имал другия, трябва да избере кой индекс ще бъде най-бърз. Внимавайте, че оптимизаторът на MySQL често прави грешки в това.)
Така че, накратко, това се очаква. Заявката не казва как за извличане на данните, по-скоро пише какво данни за извличане. Оптимизаторът на базата данни трябва да намери най-бързия начин да я извлече.
Може да намерите индекс и на и двете колони, в реда (public_key,created_on_date) е предпочитан и в двата случая и ускорява вашата заявка. Това е така, защото MySQL може да използва само един индекс на таблица (на заявка). Освен това датата отива в края, защото сканирането на диапазон може да се извърши ефективно само на последната колона в индекса.
[InnoDB всъщност има друг слой на индиректност, вярвам, но това просто би объркало идеята. Няма значение за обяснението.]