sql >> Database >  >> RDS >> Mysql

Hoe werken MySQL-indexen?

Het eerste dat u moet weten, is dat indexen een manier zijn om te voorkomen dat u de volledige tabel hoeft te scannen om het resultaat te verkrijgen waarnaar u op zoek bent.

Er zijn verschillende soorten indexen en ze zijn geïmplementeerd in de opslaglaag, dus er is geen standaard tussen en ze zijn ook afhankelijk van de opslagengine die je gebruikt.

InnoDB en de B+Tree-index

Voor InnoDB is het meest voorkomende indextype de op B+Tree gebaseerde index, die de elementen in een gesorteerde volgorde opslaat. U hoeft ook geen toegang te krijgen tot de echte tabel om de geïndexeerde waarden te krijgen, waardoor uw zoekopdracht veel sneller terugkeert.

Het "probleem" met dit indextype is dat je moet zoeken naar de meest linkse waarde om de index te gebruiken. Dus als uw index twee kolommen heeft, zeg achternaam en voornaam, is de volgorde waarin u deze velden doorzoekt heel belangrijk .

Dus, gezien de volgende tabel:

CREATE TABLE person (
    last_name VARCHAR(50) NOT NULL,
    first_name VARCHAR(50) NOT NULL,
    INDEX (last_name, first_name)
);

Deze zoekopdracht zou gebruik maken van de index:

SELECT last_name, first_name FROM person
WHERE last_name = "John" AND first_name LIKE "J%"

Maar de volgende niet

SELECT last_name, first_name FROM person WHERE first_name = "Constantine"

Omdat je de first_name . opvraagt kolom eerst en het is niet de meest linkse kolom in de index.

Dit laatste voorbeeld is nog erger:

SELECT last_name, first_name FROM person WHERE first_name LIKE "%Constantine"

Omdat je nu het meest rechtse deel van het meest rechtse veld in de index vergelijkt.

De hash-index

Dit is een ander indextype dat helaas alleen de geheugenbackend ondersteunt. Het is razendsnel, maar alleen handig voor volledige zoekopdrachten, wat betekent dat u het niet kunt gebruiken voor bewerkingen zoals > , < of LIKE .

Omdat het alleen werkt voor de geheugenbackend, zul je het waarschijnlijk niet vaak gebruiken. Het belangrijkste geval dat ik nu kan bedenken, is dat je een tijdelijke tabel in het geheugen maakt met een reeks resultaten van een andere selectie en een heleboel andere selecties uitvoert in deze tijdelijke tabel met behulp van hash-indexen.

Als je een grote VARCHAR . hebt veld, kunt u het gebruik van een hash-index "emuleren" bij gebruik van een B-Tree, door een andere kolom te maken en er een hash van de grote waarde op op te slaan. Stel dat u een url in een veld opslaat en dat de waarden vrij groot zijn. U kunt ook een geheel getal maken met de naam url_hash en gebruik een hash-functie zoals CRC32 of een andere hash-functie om de url te hashen bij het invoegen. En dan, wanneer u deze waarde moet opvragen, kunt u zoiets als dit doen:

SELECT url FROM url_table WHERE url_hash=CRC32("http://gnu.org");

Het probleem met het bovenstaande voorbeeld is dat sinds de CRC32 functie een vrij kleine hash genereert, krijg je veel botsingen in de gehashte waarden. Als u exacte waarden nodig heeft, kunt u dit probleem als volgt oplossen:

SELECT url FROM url_table 
WHERE url_hash=CRC32("http://gnu.org") AND url="http://gnu.org";

Het is nog steeds de moeite waard om dingen te hashen, zelfs als het botsingsgetal hoog is, omdat je alleen de tweede vergelijking (de string-één) met de herhaalde hashes uitvoert.

Helaas moet je met deze techniek nog steeds de tafel raken om de url . te vergelijken veld.

Afsluiten

Enkele feiten die u kunt overwegen elke keer dat u over optimalisatie wilt praten:

  1. Integer-vergelijking is veel sneller dan string-vergelijking. Het kan worden geïllustreerd met het voorbeeld over de emulatie van de hash-index in InnoDB .

  2. Misschien maakt het toevoegen van extra stappen in een proces het sneller, niet langzamer. Het kan worden geïllustreerd door het feit dat u een SELECT . kunt optimaliseren door het in twee stappen te splitsen, waarbij de eerste waarden opslaat in een nieuw gemaakte in-memory tabel en vervolgens de zwaardere query's op deze tweede tabel uitvoert.

MySQL heeft ook andere indexen, maar ik denk dat de B+Tree-index de meest gebruikte ooit is en de hash-index is goed om te weten, maar je kunt de andere vinden in de MySQL-documentatie .

Ik raad je ten zeerste aan om het boek "High Performance MySQL" te lezen, het antwoord hierboven was zeker gebaseerd op het hoofdstuk over indexen.



  1. Coalesce-functie gebruiken in Oracle

  2. Hoe verschillende records uit een tabel in SQL Server te halen - SQL Server / TSQL-zelfstudie 112

  3. Onjuiste syntaxis in de buurt van het trefwoord 'met'...vorige instructie moet worden afgesloten met een puntkomma

  4. Hoe Typeof() werkt in SQLite