sql >> Database >  >> RDS >> MariaDB

Indexen in MySQL begrijpen:deel één

Indexen in MySQL zijn een zeer complex beest. We hebben in het verleden MySQL-indexen behandeld, maar we hebben er nooit dieper in gedoken - dat zullen we doen in deze reeks blogposts. Deze blogpost zou moeten dienen als een zeer algemene gids voor indexen, terwijl de andere delen van deze serie een beetje dieper in deze onderwerpen zullen duiken.

Wat zijn indexen?

In het algemeen, zoals al opgemerkt in een eerdere blogpost over indexen, is een index een alfabetische lijst van records met verwijzingen naar de pagina's waarop ze worden vermeld. In MySQL is een index een gegevensstructuur die het meest wordt gebruikt om snel rijen te vinden. Je hoort misschien ook de term "sleutels" - het verwijst ook naar indexen.

Wat doen indexen?

In MySQL worden indexen gebruikt om snel rijen met specifieke kolomwaarden te vinden en om te voorkomen dat de hele tabel wordt doorgelezen om rijen te vinden die relevant zijn voor de zoekopdracht. Indexen worden meestal gebruikt wanneer de gegevens die zijn opgeslagen in een databasesysteem (bijvoorbeeld MySQL) groter worden, want hoe groter de tabel, hoe groter de kans dat u baat kunt hebben bij indexen.

MySQL-indextypen

Wat MySQL betreft, heb je misschien gehoord dat het meerdere soorten indexen heeft:

  • Een B-Tree INDEX - een dergelijke index wordt vaak gebruikt om SELECT-query's die overeenkomen met een WHERE-clausule te versnellen. Een dergelijke index kan worden gebruikt op velden waar waarden niet uniek hoeven te zijn, het accepteert ook NULL-waarden.

  • EEN FULLTEXT INDEX - een dergelijke index wordt gebruikt om de volledige tekst zoekmogelijkheden te gebruiken. Dit type index vindt trefwoorden in de tekst in plaats van waarden rechtstreeks te vergelijken met de waarden in de index.

  • Een UNIEKE INDEX wordt vaak gebruikt om dubbele waarden uit een tabel te verwijderen. Dwingt de uniciteit van rijwaarden af.

  • EEN PRIMARY KEY is ook een index - het wordt vaak gebruikt in combinatie met velden met een AUTO_INCREMENT-attribuut. Dit type index accepteert geen NULL-waarden en eenmaal ingesteld, kunnen de waarden in de kolom met een PRIMAIRE SLEUTEL niet worden gewijzigd.

  • A DESCENDING INDEX is een index die rijen in aflopende volgorde opslaat. Dit type index is geïntroduceerd in MySQL 8.0 - MySQL zal dit type index gebruiken wanneer een aflopende volgorde wordt gevraagd door de query.

Optimale gegevenstypen kiezen voor indexen in MySQL

Wat indexen betreft, moet u er ook rekening mee houden dat MySQL een grote verscheidenheid aan gegevenstypen ondersteunt en dat sommige gegevenstypen niet samen met bepaalde soorten indexen kunnen worden gebruikt (bijvoorbeeld FULLTEXT indexen kunnen alleen worden gebruikt voor op tekst gebaseerde (CHAR, VARCHAR of TEXT) kolommen - ze kunnen niet worden gebruikt voor andere gegevenstypen), dus voordat u de indexen voor uw databaseontwerp kiest, moet u beslissen op welk gegevenstype u gaat gebruiken de kolom in kwestie (beslis wat voor soort gegevensklasse je gaat opslaan:ga je getallen opslaan? Stringwaarden? Zowel getallen als stringwaarden? enz.), bepaal vervolgens het bereik van de waarden die je gaat opslaan (kies degene die u niet denkt te overschrijden, omdat het later een tijdrovende taak kan zijn om het gegevenstypebereik te vergroten - we raden u aan om een ​​eenvoudig gegevenstype te gebruiken), en als u niet van plan bent om NULL te gebruiken waarden in uw kolommen, specificeer uw velden als NOT NULL wanneer u kunt - wanneer een nullable co lumn is geïndexeerd, het vereist een extra byte per invoer.

Kiezen van optimale tekensets en sorteringen voor indexen in MySQL

Houd er naast gegevenstypen ook rekening mee dat elk teken in MySQL ruimte in beslag neemt. UTF-8-tekens kunnen bijvoorbeeld elk tussen de 1 en 4 bytes in beslag nemen, dus u kunt indexering van bijvoorbeeld 255 tekens vermijden en slechts 50 of 100 tekens gebruiken voor een bepaalde kolom.

De voor- en nadelen van het gebruik van indexen in MySQL

Het belangrijkste voordeel van het gebruik van indexen in MySQL is de verbeterde prestatie van zoekopdrachten die overeenkomen met een WHERE-clausule - indexen versnellen SELECT-query's die overeenkomen met een WHERE-clausule omdat MySQL niet de hele tabel doorleest om rijen te vinden relevant voor de vraag. Houd er echter rekening mee dat indexen hun eigen nadelen hebben. De belangrijkste zijn als volgt:

  • Indexen nemen schijfruimte in beslag.

  • Indexen verslechteren de prestaties van INSERT-, UPDATE- en DELETE-query's - wanneer gegevens worden bijgewerkt, moet de index samen met het bijgewerkt.

  • MySQL beschermt u niet tegen het gebruik van meerdere typen indexen tegelijk. Met andere woorden, u kunt een PRIMAIRE SLEUTEL, een INDEX en een UNIEKE INDEX in dezelfde kolom gebruiken - MySQL beschermt u niet tegen zo'n fout.

Als u vermoedt dat sommige van uw zoekopdrachten langzamer worden, overweeg dan eens een kijkje te nemen in het tabblad Querymonitor van ClusterControl - door de querymonitor in te schakelen, kunt u zien wanneer een bepaalde zoekopdracht voor het laatst is gezien en het maximum en gemiddelde uitvoeringstijd die u kan helpen om de beste indexen voor uw tabel te kiezen.

Hoe kies ik de beste index om te gebruiken?

Om de beste index te kiezen die u wilt gebruiken, kunt u de ingebouwde mechanismen van MySQL gebruiken. U kunt bijvoorbeeld de query-explainer gebruiken - de EXPLAIN-query. Het zal uitleggen welke tabel wordt gebruikt, of deze partities heeft of niet, welke indexen kunnen worden gebruikt en welke sleutel (index) wordt gebruikt. Het retourneert ook de indexlengte en het aantal rijen dat uw zoekopdracht retourneert:

mysql> EXPLAIN SELECT * FROM demo_table WHERE demo_field = ‘demo’\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: demo_table
   partitions: NULL
         type: ref
possible_keys: demo_field
          key: demo_field
      key_len: 1022
          ref: const
         rows: 1
     filtered: 100.00
        Extra: NULL
1 row in set, 1 warning (0.00 sec)

Houd er in dit geval rekening mee dat indexen vaak worden gebruikt om MySQL te helpen efficiënt gegevens op te halen wanneer gegevenssets groter zijn dan normaal. Als uw tabel klein is, hoeft u misschien geen indexen te gebruiken, maar als u ziet dat uw tabellen steeds groter worden, is de kans groot dat u baat heeft bij een index.

Om de beste index voor uw specifieke scenario te kiezen, moet u er rekening mee houden dat indexen ook een belangrijke oorzaak van prestatieproblemen kunnen zijn. Houd er rekening mee dat of MySQL de indexen effectief zal gebruiken of niet, afhankelijk is van een aantal factoren, waaronder het ontwerp van uw zoekopdrachten, de indexen die worden gebruikt, de typen indexen die worden gebruikt, ook uw databasebelasting op het moment dat de zoekopdracht wordt uitgevoerd en andere dingen. Hier zijn een paar dingen waarmee u rekening moet houden bij het gebruik van indexen in MySQL:

  • Hoeveel gegevens heeft u? Misschien is een deel ervan overbodig?

  • Welke zoekopdrachten gebruikt u? Zouden uw zoekopdrachten LIKE-clausules gebruiken? Hoe zit het met bestellen?

  • Wat voor soort index zou u moeten gebruiken om de prestaties van uw zoekopdrachten te verbeteren?

  • Zouden uw indexen groot of klein zijn? Zou u een index op een voorvoegsel van de kolom moeten gebruiken om de grootte kleiner te maken?

Het is vermeldenswaard dat u waarschijnlijk ook moet vermijden om meerdere typen indexen (bijv. een B-Tree-index, een UNIEKE INDEX en een PRIMAIRE SLEUTEL) in dezelfde kolom te gebruiken.

Queryprestaties verbeteren met indexen

Om de queryprestaties met indexen te verbeteren, moet u uw query's bekijken - het EXPLAIN-statement kan daarbij helpen. Over het algemeen zijn hier een paar dingen waar u rekening mee moet houden als u wilt dat uw indexen de prestaties van uw zoekopdrachten verbeteren:

  • Vraag alleen aan de database wat je nodig hebt. In de meeste gevallen zal het gebruik van de SELECT-kolom sneller zijn dan het gebruik van SELECT * (dat is het geval zonder ook indexen te gebruiken)

  • Een B-tree-index kan geschikt zijn als u zoekt naar exacte waarden (bijv. SELECT * FROM demo_table WHERE some_field ='x') of als u naar waarden wilt zoeken met behulp van jokertekens (bijv. SELECT * FROM demo_table WHERE some_field LIKE 'demo%' - in dit geval moet u er rekening mee houden dat het gebruik van LIKE-query's met alles aan het begin ervan voldoende kan zijn meer kwaad dan goed - vermijd het gebruik van LIKE-query's met een procentteken voor de tekst die u zoekt - op die manier gebruikt MySQL mogelijk geen index omdat het niet weet waar de rijwaarde mee begint) - maar houd er rekening mee dat een B-tree-index ook kan worden gebruikt voor kolomvergelijkingen in uitdrukkingen die de gelijk (=), meer dan (>), meer dan of gelijk aan (>=), kleiner dan (<), kleiner dan of gelijk aan gebruiken (<=) of TUSSEN operatoren.

  • Een FULLTEXT-index kan geschikt zijn als u merkt dat u volledige tekst gebruikt (MATCH ... AGAINST( )) zoekopdrachten of als uw database zo is ontworpen dat alleen op tekst gebaseerde kolommen worden gebruikt - FULLTEXT-indexen kunnen TEXT-, CHAR- of VARCHAR-kolommen gebruiken, ze kunnen niet worden gebruikt voor andere typen kolommen.

  • Een dekkende index kan handig zijn als u query's wilt uitvoeren zonder extra I/O-reads op grote tabellen . Om een ​​dekkingsindex te maken, bedek je de WHERE-, GROUP BY- en SELECT-clausules die door de query worden gebruikt.

We zullen in de komende delen van deze blogserie verder kijken naar de typen indexen, maar in het algemeen, als u zoekopdrachten gebruikt zoals SELECT * FROM demo_table WHERE some_field ='x' a B-tree INDEX zou kunnen passen, als u MATCH() AGAINST()-query's gebruikt, moet u waarschijnlijk een FULLTEXT-index bekijken, als uw tabel zeer lange rijwaarden heeft, moet u waarschijnlijk een deel van de kolom indexeren.

Hoeveel indexen moet u hebben?

Als je ooit indexen hebt gebruikt om de prestaties van je SELECT-query's te verbeteren, heb je jezelf waarschijnlijk een vraag gesteld:hoeveel indexen zou je eigenlijk moeten hebben? Om dit te begrijpen, moet u de volgende dingen in gedachten houden:

  1. Indexen zijn meestal het meest effectief bij grote hoeveelheden gegevens.

  2. MySQL gebruikt slechts één index per SELECT-instructie in een query (subquery's worden gezien als afzonderlijke instructies) - gebruik de EXPLAIN-query om erachter te komen welke indexen het meest effectief zijn voor de query's die u gebruikt.

  3. Indexen zouden al uw SELECT-instructies snel genoeg moeten maken zonder al te veel schijfruimte in gevaar te brengen - "snel genoeg" , is echter relatief, dus je zou moeten experimenteren.

Indexen en opslagengines

Als je met indexen in MySQL werkt, houd er dan rekening mee dat er bepaalde beperkingen kunnen zijn als je verschillende engines gebruikt (bijvoorbeeld als je MyISAM gebruikt in plaats van InnoDB). We zullen in een aparte blog in meer detail treden, maar hier zijn enkele ideeën:

  • Het maximum aantal indexen per MyISAM- en InnoDB-tabellen is 64, het maximum aantal kolommen per index in beide opslagengines is 16.

  • De maximale sleutellengte voor InnoDB is 3500 bytes - de maximale sleutellengte voor MyISAM is 1000 bytes.

  • De fulltext-indexen hebben beperkingen in bepaalde storage-engines - de InnoDB fulltext-indexen hebben bijvoorbeeld 36 stopwoorden, MyISAM stopwoordenlijst is iets groter met 143 stopwoorden. InnoDB leidt deze stopwoorden af ​​van de variabele innodb_ft_server_stopword_table, terwijl MyISAM deze stopwoorden afleidt van het bestand storage/myisam/ft_static.c - alle woorden die in het bestand worden gevonden, worden als stopwoorden behandeld.

  • MyISAM was de enige opslagengine met ondersteuning voor full-text zoekopties tot MySQL 5.6 (MySQL 5.6. 4 om precies te zijn) kwam rond, wat betekent dat InnoDB full-text indexen ondersteunt sinds MySQL 5.6.4. Wanneer een FULLTEXT-index in gebruik is, vindt deze trefwoorden in de tekst in plaats van waarden rechtstreeks te vergelijken met de waarden in de index.

  • Indexen spelen een zeer belangrijke rol voor InnoDB - InnoDB vergrendelt rijen wanneer het toegang krijgt, dus een verminderd aantal rijen InnoDB-toegangen kunnen vergrendelingen verminderen.

  • MySQL stelt u in staat dubbele indexen op dezelfde kolom te gebruiken.

  • Bepaalde opslag-engines hebben bepaalde standaardtypen indexen (bijv. voor de MEMORY-opslagengine is het standaardindextype hash )

Samenvatting

In dit deel over indexen in MySQL hebben we een aantal algemene zaken doorgenomen met betrekking tot indexen in dit relationele databasebeheersysteem. In de komende blogposts gaan we dieper in op het gebruik van indexen in MySQL, inclusief het gebruik van indexen in bepaalde storage-engines enz. - we zullen ook uitleggen hoe ClusterControl kan worden gebruikt om uw prestatiedoelen in MySQL te bereiken.


  1. Hoe de laatste rij per groep te krijgen in PostgreSQL

  2. Stapsgewijze handleiding voor het installeren van MySQL op Windows

  3. ORA-01264 in fysieke stand-by

  4. Hoe splits ik een string zodat ik toegang heb tot item x?