MariaDB
 sql >> Database >  >> RDS >> MariaDB

Comprendere gli indici in MySQL:parte prima

Gli indici in MySQL sono una bestia molto complessa. Abbiamo trattato gli indici MySQL in passato, ma non ci siamo mai immersi più a fondo:lo faremo in questa serie di post sul blog. Questo post sul blog dovrebbe fungere da guida molto generale agli indici, mentre le altre parti di queste serie approfondiranno un po' questi argomenti.

Cosa sono gli indici?

In generale, come già notato in un precedente post sul blog sugli indici, un indice è un elenco alfabetico di record con riferimenti alle pagine in cui sono menzionati. In MySQL, un indice è una struttura di dati che viene utilizzata più comunemente per trovare rapidamente le righe. Potresti anche sentire il termine "chiavi":si riferisce anche agli indici.

Cosa fanno gli indici?

In MySQL gli indici vengono utilizzati per trovare rapidamente righe con valori di colonna specifici e per impedire la lettura dell'intera tabella per trovare righe rilevanti per la query. Gli indici vengono utilizzati principalmente quando i dati archiviati in un sistema di database (ad esempio MySQL) diventano più grandi perché più grande è la tabella, maggiore è la probabilità che tu possa trarre vantaggio dagli indici.

Tipi di indice MySQL

Per quanto riguarda MySQL, potresti aver sentito parlare di diversi tipi di indici:

  • A B-Tree INDEX - tale indice viene spesso utilizzato per velocizzare le query SELECT che corrispondono a una clausola WHERE. Tale indice può essere utilizzato su campi in cui i valori non devono essere univoci, accetta anche valori NULL.

  • UN FULLTEXT INDEX - tale indice viene utilizzato per utilizzare le capacità di ricerca full text. Questo tipo di indice trova le parole chiave nel testo invece di confrontare direttamente i valori con i valori nell'indice.

  • Un INDICE UNICO viene spesso utilizzato per rimuovere valori duplicati da una tabella. Impone l'unicità dei valori di riga.

  • Una CHIAVE PRIMARIA è anche un indice:è spesso usata insieme ai campi che hanno un attributo AUTO_INCREMENT. Questo tipo di indice non accetta valori NULL e una volta impostati, i valori nella colonna che ha una CHIAVE PRIMARIA non possono essere modificati.

  • Un indice discendente è un indice che memorizza le righe in ordine decrescente. Questo tipo di indice è stato introdotto in MySQL 8.0:MySQL utilizzerà questo tipo di indice quando la query richiede un ordine decrescente.

Scelta dei tipi di dati ottimali per gli indici in MySQL

Per quanto riguarda gli indici, c'è anche la necessità di tenere presente che MySQL supporta un'ampia varietà di tipi di dati e alcuni tipi di dati non possono essere utilizzati insieme a determinati tipi di indici (ad esempio, FULLTEXT gli indici possono essere usati solo su colonne testuali (CHAR, VARCHAR o TEXT) - non possono essere usati su nessun altro tipo di dati), quindi prima di scegliere effettivamente gli indici per la progettazione del tuo database, decidi il tipo di dati che utilizzerai su la colonna in questione (decidi che tipo di classe di dati intendi memorizzare:memorizzerai i numeri? Valori stringa? Sia i numeri che i valori stringa? ecc.), quindi decidi l'intervallo dei valori che intendi memorizzare (scegli quello che pensi di non superare perché aumentare l'intervallo del tipo di dati può essere un'attività che richiede tempo in seguito - ti consigliamo di scegliere di utilizzare un tipo di dati semplice) e se non intendi utilizzare NULL valori nelle tue colonne, specifica i tuoi campi come NOT NULL ogni volta che puoi - quando un co nullable lumn è indicizzato, richiede un byte aggiuntivo per voce.

Scelta di set di caratteri e regole di confronto ottimali per gli indici in MySQL

Oltre ai tipi di dati, tieni anche presente che ogni carattere in MySQL occupa spazio. Ad esempio, i caratteri UTF-8 possono richiedere da 1 a 4 byte ciascuno, quindi potresti voler evitare l'indicizzazione, ad esempio, 255 caratteri e utilizzare, ad esempio, 50 o 100 caratteri per una determinata colonna.

I vantaggi e gli svantaggi dell'utilizzo degli indici in MySQL

Il vantaggio principale dell'utilizzo degli indici in MySQL è l'aumento delle prestazioni delle query di ricerca che corrispondono a una clausola WHERE:gli indici accelerano le query SELECT che corrispondono a una clausola WHERE perché MySQL non legge l'intera tabella per trovare le righe pertinente alla domanda. Tuttavia, tieni presente che gli indici hanno i loro svantaggi. I principali sono i seguenti:

  • Gli indici consumano spazio su disco.

  • Gli indici peggiorano le prestazioni delle query INSERT, UPDATE e DELETE - quando i dati vengono aggiornati, l'indice deve essere aggiornato insieme ad esso.

  • MySQL non ti protegge dall'utilizzo di più tipi di indici contemporaneamente. In altre parole, puoi usare una CHIAVE PRIMARIA, un INDICE e un INDICE UNICO sulla stessa colonna:MySQL non ti protegge dal fare un errore del genere.

Se sospetti che alcune delle tue query stiano diventando più lente, prendi in considerazione la possibilità di dare un'occhiata alla scheda Query Monitor di ClusterControl:abilitando Query Monitor puoi vedere quando una determinata query è stata vista l'ultima volta e il suo massimo e il tempo medio di esecuzione che può aiutarti a scegliere i migliori indici per la tua tabella.

Come scegliere il miglior indice da utilizzare?

Per scegliere l'indice migliore da utilizzare, puoi utilizzare i meccanismi integrati di MySQL. Ad esempio, puoi utilizzare la spiegazione della query:la query EXPLAIN. Spiegherà quale tabella viene utilizzata, se ha partizioni o meno, quali indici è possibile utilizzare e quale chiave (indice) viene utilizzata. Restituirà anche la lunghezza dell'indice e la quantità di righe restituite dalla query:

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)

In questo caso, tieni presente che gli indici vengono spesso utilizzati per aiutare MySQL a recuperare i dati in modo efficiente quando i set di dati sono più grandi del solito. Se la tua tabella è piccola, potresti non aver bisogno di utilizzare gli indici, ma se vedi che le tue tabelle stanno diventando sempre più grandi, è probabile che tu possa trarre vantaggio da un indice.

Per scegliere l'indice migliore da utilizzare per il tuo scenario specifico, tieni presente che anche gli indici possono essere una delle principali cause di problemi di prestazioni. Tieni presente che se MySQL utilizzerà in modo efficace gli indici o meno dipende da un paio di fattori tra cui la progettazione delle query, gli indici in uso, i tipi di indici in uso, anche il carico del database al momento dell'esecuzione della query e altre cose. Ecco un paio di cose da considerare quando si utilizzano gli indici in MySQL:

  • Quanti dati hai? Forse in parte è ridondante?

  • Quali query utilizzi? Le tue domande userebbero le clausole LIKE? Che ne dici di ordinare?

  • Che tipo di indice dovresti utilizzare per migliorare le prestazioni delle tue query?

  • I tuoi indici sarebbero grandi o piccoli? Dovresti utilizzare un indice su un prefisso della colonna per ridurne le dimensioni?

Vale la pena notare che probabilmente dovresti evitare di utilizzare più tipi di indici (ad esempio un indice B-Tree, un UNIQUE INDEX e una PRIMARY KEY) anche sulla stessa colonna.

Miglioramento delle prestazioni delle query con gli indici

Per migliorare le prestazioni delle query con gli indici, devi dare un'occhiata alle tue query:l'istruzione EXPLAIN può aiutarti. In generale, ecco un paio di cose che dovresti considerare se vuoi che i tuoi indici migliorino le prestazioni delle tue query:

  • Chiedi al database solo ciò di cui hai bisogno. Nella maggior parte dei casi, l'utilizzo della colonna SELECT sarà più veloce rispetto all'utilizzo di SELECT * (questo è il caso senza utilizzare anche gli indici)

  • Un indice B-tree potrebbe essere adatto se cerchi valori esatti (ad es. SELECT * FROM demo_table WHERE some_field ='x') o se vuoi cercare valori usando i caratteri jolly (ad es. SELECT * FROM demo_table WHERE some_field LIKE 'demo%' - in questo caso, tieni presente che l'utilizzo di query LIKE con qualsiasi cosa all'inizio potrebbe funzionare più danno che bene - evita di usare query LIKE con un segno di percentuale davanti al testo che stai cercando - in questo modo MySQL potrebbe non utilizzare un indice perché non sa da cosa inizia il valore della riga) - anche se tieni presente che un indice B-tree può essere utilizzato anche per confronti di colonne in espressioni che utilizzano uguale (=), maggiore di (>), maggiore o uguale a (>=), minore di (<), minore o uguale a (<=) o TRA operatori.

  • Un indice FULLTEXT potrebbe essere adatto se ti ritrovi a utilizzare il testo completo (MATCH ... AGAINST( )) query di ricerca o se il database è progettato in modo tale da utilizzare solo colonne basate su testo - Gli indici FULLTEXT possono utilizzare colonne TEXT, CHAR o VARCHAR, non possono essere utilizzati su altri tipi di colonne.

  • Un indice di copertura potrebbe essere utile se si desidera eseguire query senza ulteriori letture di I/O su grandi tabelle . Per creare un indice di copertura, copri le clausole WHERE, GROUP BY e SELECT utilizzate dalla query.

Analizzeremo ulteriormente i tipi di indici nelle prossime parti di questa serie di blog, ma in generale, se utilizzi query come SELECT * FROM demo_table WHERE some_field ='x' a B-tree INDEX potrebbe essere adatto, se usi le query MATCH() AGAINST() dovresti probabilmente esaminare un indice FULLTEXT, se la tua tabella ha valori di riga molto lunghi, dovresti probabilmente esaminare l'indicizzazione di una parte della colonna.

Quanti indici dovresti avere?

Se hai mai utilizzato indici per migliorare le prestazioni delle tue query SELECT, probabilmente ti sei posto una domanda:quanti indici dovresti effettivamente avere? Per capirlo, devi tenere a mente quanto segue:

  1. Gli indici sono generalmente i più efficaci con grandi quantità di dati.

  2. MySQL usa solo un indice per ogni istruzione SELECT in una query (le sottoquery sono viste come istruzioni separate) - usa la query EXPLAIN per scoprire quali indici sono più efficaci per le query che utilizzi.

  3. Gli indici dovrebbero rendere tutte le tue istruzioni SELECT abbastanza veloci senza compromettere troppo lo spazio su disco - "abbastanza veloci" , tuttavia, è relativo, quindi dovresti sperimentare.

Indici e motori di archiviazione

Quando hai a che fare con gli indici in MySQL, tieni anche presente che potrebbero esserci alcuni tipi di limitazioni se usi vari motori (ad esempio se usi MyISAM invece di InnoDB). Entreremo più nel dettaglio in un blog separato, ma ecco alcune idee:

  • Il numero massimo di indici per le tabelle MyISAM e InnoDB è 64, il numero massimo di colonne per indice in entrambe motori di archiviazione è 16.

  • La lunghezza massima della chiave per InnoDB è 3500 byte - la lunghezza massima della chiave per MyISAM è 1000 byte.

  • Gli indici fulltext hanno limitazioni in alcuni motori di archiviazione, ad esempio, gli indici fulltext InnoDB hanno 36 stopword, MyISAM l'elenco delle stopword è un po' più grande con 143 stopword. InnoDB deriva queste stopword dalla variabile innodb_ft_server_stopword_table mentre MyISAM deriva queste stopword dal file storage/myisam/ft_static.c - tutte le parole che si trovano nel file verranno trattate come stopword.

  • MyISAM era l'unico motore di archiviazione con il supporto per le opzioni di ricerca full-text fino a MySQL 5.6 (MySQL 5.6. 4 per l'esattezza) è venuto a significare che InnoDB supporta indici full-text da MySQL 5.6.4. Quando un indice FULLTEXT è in uso, trova le parole chiave nel testo invece di confrontare i valori direttamente con i valori nell'indice.

  • Gli indici svolgono un ruolo molto importante per InnoDB - InnoDB blocca le righe quando vi accede, quindi un numero ridotto di righe a cui InnoDB accede possono ridurre i blocchi.

  • MySQL consente di utilizzare indici duplicati sulla stessa colonna.

  • Alcuni motori di archiviazione hanno determinati tipi di indici predefiniti (ad es. per il motore di archiviazione MEMORY il tipo di indice predefinito è hash )

Riepilogo

In questa parte sugli indici in MySQL, abbiamo esaminato alcune cose generali relative agli indici in questo sistema di gestione di database relazionali. Nei prossimi post del blog analizzeremo alcuni scenari più approfonditi sull'utilizzo degli indici in MySQL, incluso l'utilizzo degli indici in determinati motori di archiviazione, ecc. - spiegheremo anche come ClusterControl può essere utilizzato per raggiungere i tuoi obiettivi di prestazioni in MySQL.