Mysql
 sql >> Database >  >> RDS >> Mysql

Indici MySQL:quali sono le migliori pratiche in base a questa tabella e query

Questa domanda:

SELECT *
FROM listings
WHERE (publishedon BETWEEN 1441105258 AND 1443614458) AND
      (published = 1) AND
      (cat_id in (1,2,3,4,5)) AND
      (source_id in (1,2,3,4,5));

È difficile da ottimizzare con solo indici. L'indice migliore è quello che inizia con published e poi ha le altre colonne -- non è chiaro quale dovrebbe essere il loro ordine. Il motivo è perché tutti tranne published non stanno usando = .

Poiché il tuo problema di prestazioni è su un ordinamento, ciò suggerisce che vengono restituite molte righe. Tipicamente, un indice viene utilizzato per soddisfare il WHERE clausola prima che l'indice possa essere utilizzato per ORDER BY . Ciò rende difficile l'ottimizzazione.

Suggerimenti. . . Nessuno è così eccezionale:

  • Se hai intenzione di accedere ai dati per mese, potresti prendere in considerazione la possibilità di partizionare i dati per mese. Ciò renderà la query senza ORDER BY più veloce, ma non aiuterà il ORDER BY .
  • Prova vari ordini di colonne dopo la published nell'indice. Potresti trovare le colonne più selettive. Ma, ancora una volta, questo velocizza la query prima dell'ordinamento.
  • Pensa ai modi in cui puoi strutturare la query in modo da avere più condizioni di uguaglianza nel WHERE clausola o per restituire un insieme di dati più piccolo.
  • (Non proprio consigliato) Metti un indice su published e la colonna di ordinazione. Quindi utilizzare una sottoquery per recuperare i dati. Inserisci le condizioni di disuguaglianza (IN e così via) nella query esterna. La sottoquery utilizzerà l'indice per l'ordinamento e quindi filtrerà i risultati.

Il motivo per cui l'ultimo non è raccomandato è perché SQL (e MySQL) non garantiscono l'ordinamento dei risultati da una sottoquery. Tuttavia, poiché MySQL materializza le sottoquery, i risultati sono davvero in ordine. Non mi piace usare effetti collaterali non documentati, che possono cambiare da versione a versione.