sql >> Databasteknik >  >> RDS >> MariaDB

Förstå index i MySQL:Del ett

Index i MySQL är en mycket komplex best. Vi har täckt MySQL-index tidigare, men vi har aldrig tagit en djupare dykning i dem – det kommer vi att göra i dessa serier av blogginlägg. Det här blogginlägget ska fungera som en mycket allmän guide till index medan de andra delarna av dessa serier kommer att dyka lite djupare in i dessa ämnen.

Vad är index?

I allmänhet, som redan noterats i ett tidigare blogginlägg om index, är ett index en alfabetisk lista över poster med hänvisningar till sidorna där de nämns. I MySQL är ett index en datastruktur som oftast används för att snabbt hitta rader. Du kanske också hör termen "nycklar" - det syftar också på index.

Vad gör index?

I MySQL används index för att snabbt hitta rader med specifika kolumnvärden och för att förhindra att man läser igenom hela tabellen för att hitta eventuella rader som är relevanta för frågan. Index används oftast när data som lagras i ett databassystem (till exempel MySQL) blir större eftersom ju större tabellen är, desto större är sannolikheten att du kan dra nytta av index.

MySQL-indextyper

När det gäller MySQL kanske du har hört talas om att det har flera typer av index:

  • Ett B-Tree INDEX - ett sådant index används ofta för att snabba upp SELECT-frågor som matchar en WHERE-sats. Ett sådant index kan användas på fält där värden inte behöver vara unika, det accepterar även NULL-värden.

  • ETT FULLTEXTINDEX - ett sådant index används för att använda fulltextsökningsmöjligheter. Den här typen av index hittar nyckelord i texten istället för att direkt jämföra värden med värdena i indexet.

  • ETT UNIKT INDEX används ofta för att ta bort dubbletter av värden från en tabell. Framtvingar unika radvärden.

  • En PRIMÄRNYCKEL är också ett index - den används ofta tillsammans med fält som har ett AUTO_INCREMENT-attribut. Den här typen av index accepterar inte NULL-värden och när de väl har ställts in kan värdena i kolumnen som har en PRIMÄRNYCKEL inte ändras.

  • ETT SIGANDE INDEX är ett index som lagrar rader i fallande ordning. Denna typ av index introducerades i MySQL 8.0 - MySQL kommer att använda denna typ av index när en fallande ordning efterfrågas av frågan.

Välja optimala datatyper för index i MySQL

När det gäller index, måste man också komma ihåg att MySQL stöder en mängd olika datatyper och att vissa datatyper inte kan användas tillsammans med vissa typer av index (till exempel FULLTEXT index kan endast användas på textbaserade (CHAR, VARCHAR eller TEXT) kolumner - de kan inte användas på några andra datatyper), så innan du faktiskt väljer index för din databasdesign, bestäm vilken datatyp du ska använda på kolumnen i fråga (bestäm vilken typ av dataklass du ska lagra:ska du lagra siffror? Strängvärden? Både siffror och strängvärden? etc.), bestäm sedan intervallet för de värden du ska lagra (välj den som du inte tror att du kommer att överskrida eftersom att öka datatypintervallet kan vara en tidskrävande uppgift senare - vi rekommenderar att du väljer att använda en enkel datatyp), och om du inte tänker använda NULL värden i dina kolumner, ange dina fält som NOT NULL när du kan - när en nullbar co lumn indexeras, det kräver en extra byte per post.

Välja optimala teckenuppsättningar och sorteringar för index i MySQL

Bortsett från datatyper, kom också ihåg att varje tecken i MySQL tar upp plats. Till exempel kan UTF-8-tecken ta var som helst mellan 1 och 4 byte vardera, så du kanske vill undvika att indexera till exempel 255 tecken och bara använda t.ex. 50 eller 100 tecken för en viss kolumn.

Fördelar och nackdelar med att använda index i MySQL

Den största fördelen med att använda index i MySQL är den ökade prestandan för sökfrågor som matchar en WHERE-sats - index påskyndar SELECT-frågor som matchar en WHERE-sats eftersom MySQL inte läser igenom hela tabellen för att hitta rader relevant för frågan. Kom dock ihåg att index har sina egna nackdelar. De viktigaste är följande:

  • Index förbrukar diskutrymme.

  • Index försämrar prestandan för INSERT-, UPDATE- och DELETE-frågor - när data uppdateras måste indexet uppdateras tillsammans med den.

  • MySQL skyddar dig inte från att använda flera typer av index samtidigt. Med andra ord kan du använda en PRIMÄRNYCKEL, ett INDEX och ett UNIKT INDEX på samma kolumn - MySQL skyddar dig inte från att göra ett sådant misstag.

Om du misstänker att några av dina frågor blir långsammare, överväg att ta en titt på fliken Query Monitor i ClusterControl - genom att aktivera frågeövervakaren kan du se när en viss fråga senast sågs och dess maximala och genomsnittlig körtid som kan hjälpa dig att välja de bästa indexen för din tabell.

Hur väljer man det bästa indexet att använda?

För att välja det bästa indexet att använda kan du använda MySQL:s inbyggda mekanismer. Du kan till exempel använda frågeförklaringen - EXPLAIN-frågan. Den kommer att förklara vilken tabell som används, om den har partitioner eller inte, vilka index som är möjliga att använda och vilken nyckel (index) som används. Det kommer också att returnera indexlängden och antalet rader som din fråga returnerar:

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)

Tänk i det här fallet på att index ofta används för att hjälpa MySQL att effektivt hämta data när datamängderna är större än vanligt. Om ditt bord är litet behöver du kanske inte använda index, men om du ser att dina tabeller blir större och större är chansen stor att du kan dra nytta av ett index.

För att välja det bästa indexet att använda för ditt specifika scenario, kom dock ihåg att index också kan vara en ledande orsak till prestandaproblem. Tänk på att huruvida MySQL kommer att använda indexen effektivt eller inte beror på ett par faktorer, inklusive designen av dina frågor, indexen som används, vilka typer av index som används, även din databasbelastning vid den tidpunkt då frågan exekveras och andra saker. Här är ett par saker att tänka på när du använder index i MySQL:

  • Hur mycket data har du? Kanske är en del av det överflödigt?

  • Vilka frågor använder du? Skulle dina frågor använda LIKE-satser? Vad sägs om att beställa?

  • Vilken typ av index skulle du behöva använda för att förbättra prestandan för dina frågor?

  • Skulle dina index vara stora eller små? Skulle du behöva använda ett index på ett prefix för kolumnen för att göra dess storlek mindre?

Det är värt att notera att du förmodligen bör undvika att använda flera typer av index (t.ex. ett B-Tree-index, ett UNIKT INDEX och en PRIMÄRNYCKEL) på samma kolumn också.

Förbättra frågeprestanda med index

För att förbättra frågeprestanda med index måste du ta en titt på dina frågor - EXPLAIN-satsen kan hjälpa till med det. I allmänhet, här är ett par saker du bör tänka på om du vill att dina index ska förbättra prestandan för dina frågor:

  • Fråga bara databasen om det du behöver. I de flesta fall går det snabbare att använda SELECT-kolumnen än att använda SELECT * (det är fallet utan att använda index också)

  • Ett B-trädindex kan passa om du söker efter exakta värden (t.ex. SELECT * FROM demo_table WHERE some_field ='x') eller om du vill söka efter värden med hjälp av jokertecken (t.ex. SELECT * FROM demo_table WHERE some_field LIKE 'demo%' - i det här fallet, kom ihåg att användning av LIKE-frågor med vad som helst i början av det kan göra mer skada än nytta - undvik att använda LIKE-frågor med ett procenttecken framför texten du söker - på så sätt kanske MySQL inte använder ett index eftersom det inte vet vad radvärdet börjar med) - men kom ihåg att ett B-trädindex också kan användas för kolumnjämförelser i uttryck som använder lika (=), mer än (>), mer än eller lika med (>=), mindre än (<), mindre än eller lika med (<=) eller MELLAN operatorer.

  • Ett FULLTEXT-index kan passa om du använder fulltext (MATCH ... MOT( )) sökfrågor eller om din databas är utformad på ett sådant sätt att den bara använder textbaserade kolumner - FULLTEXT-index kan använda TEXT-, CHAR- eller VARCHAR-kolumner, de kan inte användas på några andra typer av kolumner.

  • Ett täckande index kan vara användbart om du vill köra frågor utan ytterligare I/O-läsningar på stora tabeller . För att skapa ett täckande index, täck satserna WHERE, GROUP BY och SELECT som används av frågan.

Vi kommer att titta närmare på typerna av index i de kommande delarna av den här bloggserien, men i allmänhet, om du använder frågor som SELECT * FROM demo_table WHERE some_field ='x' ett B-träd INDEX kanske passar, om du använder MATCH() AGAINST()-frågor bör du antagligen titta på ett FULLTEXT-index, om din tabell har mycket långa radvärden bör du antagligen titta på att indexera en del av kolumnen.

Hur många index bör du ha?

Om du någonsin använt index för att förbättra prestandan för dina SELECT-frågor, har du förmodligen ställt dig själv en fråga:hur många index ska du egentligen ha? För att förstå detta måste du tänka på följande:

  1. Index är vanligtvis de mest effektiva med stora datamängder.

  2. MySQL använder endast ett index per varje SELECT-sats i en fråga (underfrågor ses som separata satser) - använd EXPLAIN-frågan för att ta reda på vilka index som är mest effektiva för de frågor du använder.

  3. Index bör göra alla dina SELECT-satser tillräckligt snabba utan att kompromissa för mycket med diskutrymmet - "snabbt nog" , är dock relativt så du skulle behöva experimentera.

Index och lagringsmotorer

När du hanterar index i MySQL, tänk också på att det kan finnas vissa typer av begränsningar om du använder olika motorer (till exempel om du använder MyISAM i motsats till InnoDB). Vi kommer att gå in mer i detalj i en separat blogg, men här är några idéer:

  • Det maximala antalet index per MyISAM- och InnoDB-tabeller är 64, det maximala antalet kolumner per index i båda lagringsmotorer är 16.

  • Den maximala nyckellängden för InnoDB är 3500 byte - den maximala nyckellängden för MyISAM är 1000 byte.

  • Fulltextindexen har begränsningar i vissa lagringsmotorer - till exempel har InnoDB fulltextindexen 36 stoppord, MyISAM stoppordslistan är lite större med 143 stoppord. InnoDB härleder dessa stoppord från variabeln innodb_ft_server_stopword_table medan MyISAM härleder dessa stoppord från filen storage/myisam/ft_static.c - alla ord som finns i filen kommer att behandlas som stoppord.

  • MyISAM var den enda lagringsmotorn med stöd för fulltextsökalternativ fram till MySQL 5.6 (MySQL 5.6. 4 för att vara exakt) kom och betyder att InnoDB stöder fulltextindex sedan MySQL 5.6.4. När ett FULLTEXT-index används, hittar det nyckelord i texten istället för att jämföra värden direkt med värdena i indexet.

  • Index spelar en mycket viktig roll för InnoDB - InnoDB låser rader när den kommer åt dem, så ett minskat antal rader InnoDB-åtkomster kan minska låsningen.

  • MySQL låter dig använda dubbletter av index i samma kolumn.

  • Vissa lagringsmotorer har vissa standardtyper av index (t.ex. för MEMORY-lagringsmotorn är standardindextypen hash )

Sammanfattning

I den här delen om index i MySQL har vi gått igenom några generella saker relaterade till index i detta relationsdatabashanteringssystem. I de kommande blogginläggen kommer vi att gå igenom några mer djupgående scenarier för användning av index i MySQL inklusive användning av index i vissa lagringsmotorer etc. - vi kommer också att förklara hur ClusterControl kan användas för att uppnå dina prestationsmål i MySQL.


  1. Vilken är den perfekta verktygslådan för PL/SQL-utveckling?

  2. Hitta det maximala antalet år i följd för varje ID i en tabell (Oracle SQL)

  3. Använda JDeveloper med MySQL Database och Oracle Database på AWS RDS, del 1

  4. Hur lägger jag till en referens till MySQL-anslutningen för .NET?