Verschillende zoekstrategieën zijn zinvol voor verschillende gegevens. Met name indexscans (zoals bereik) moeten vaak zoeken om de rij daadwerkelijk te lezen. Op een gegeven moment is het doen van al die zoekopdrachten langzamer dan het helemaal niet gebruiken van de index.
Neem een triviaal voorbeeld, een tabel met drie kolommen:id (primaire sleutel), naam (geïndexeerd), verjaardag. Zeg dat het veel gegevens heeft. Als je MySQL vraagt om naar de verjaardag van Bob te zoeken, kan het dat vrij snel doen:eerst vindt het Bob in de naamindex (dit kost een paar zoekopdrachten, log(n) waarbij n het aantal rijen is), dan nog een extra zoekopdracht om lees de eigenlijke rij in het gegevensbestand en lees de verjaardag ervan. Dat is erg snel, en veel sneller dan het scannen van de hele tafel.
Overweeg vervolgens om een name like 'Z%'
. Dat is waarschijnlijk een vrij klein deel van de tafel. Dus het is nog steeds sneller om te vinden waar de Z's beginnen in de naamindex, en dan voor elk het gegevensbestand te zoeken om de rij te lezen. (Dit is een bereikscan).
Overweeg ten slotte om alle namen te vragen die beginnen met M-Z. Dat is waarschijnlijk ongeveer de helft van de gegevens. Het zou een bereikscan kunnen doen, en dan een veel van zoekt, maar willekeurig zoeken over het gegevensbestand met het uiteindelijke doel om de helft van de rijen te lezen is niet optimaal:het zou sneller zijn om gewoon een grote sequentiële lezing van het gegevensbestand uit te voeren. In dit geval wordt de index dus genegeerd.
Dit is wat je ziet - behalve in jouw geval, is er een andere sleutel waarop het kan terugvallen. (Het is ook mogelijk dat het de datumindex zou gebruiken als het de andere niet had, het zou de index moeten kiezen die het snelst is. Pas op dat de MySQL-optimizer hierin vaak fouten maakt.)
Dus, kortom, dit is te verwachten. Een zoekopdracht zegt niet hoe om de gegevens op te halen, in plaats daarvan zegt het wat gegevens op te halen. De optimalisatieprogramma van de database zou de snelste manier moeten vinden om het op te halen.
Mogelijk vindt u een index op beide kolommen, in de volgorde (public_key,created_on_date) heeft in beide gevallen de voorkeur en versnelt uw zoekopdracht. Dit komt omdat MySQL maar één index per tabel (per query) kan gebruiken. Ook komt de datum aan het einde omdat een bereikscan alleen efficiënt kan worden gedaan op de laatste kolom in een index.
[InnoDB heeft eigenlijk nog een andere laag van indirectheid, geloof ik, maar het zou het punt alleen maar verwarren. Voor de uitleg maakt het niet uit.]