Mysql
 sql >> Base de données >  >> RDS >> Mysql

Index MySQL - quelles sont les meilleures pratiques selon ce tableau et les requêtes

Cette requête :

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));

Est difficile à optimiser avec seulement des index. Le meilleur index est celui qui commence par published puis a les autres colonnes - il n'est pas clair quel devrait être leur ordre. La raison en est que tous sauf published n'utilisent pas = .

Étant donné que votre problème de performances concerne un tri, cela suggère que de nombreuses lignes sont renvoyées. Typiquement, un index est utilisé pour satisfaire le WHERE clause avant que l'index puisse être utilisé pour le ORDER BY . Cela rend cela difficile à optimiser.

Suggestions . . . Aucun n'est aussi génial :

  • Si vous avez l'intention d'accéder aux données par mois, vous pouvez envisager de partitionner les données par mois. Cela fera la requête sans le ORDER BY plus rapide, mais n'aidera pas le ORDER BY .
  • Essayez différents ordres de colonnes après published dans l'indice. Vous pourriez trouver la ou les colonnes les plus sélectives. Mais, encore une fois, cela accélère la requête avant le tri.
  • Pensez aux façons dont vous pouvez structurer la requête pour avoir plus de conditions d'égalité dans WHERE clause ou pour renvoyer un ensemble de données plus petit.
  • (Pas vraiment recommandé) Mettre un index sur published et la colonne de commande. Utilisez ensuite une sous-requête pour récupérer les données. Mettez les conditions d'inégalité (IN et ainsi de suite) dans la requête externe. La sous-requête utilisera l'index pour le tri, puis filtrera les résultats.

La raison pour laquelle la dernière n'est pas recommandée est que SQL (et MySQL) ne garantissent pas l'ordre des résultats d'une sous-requête. Cependant, comme MySQL matérialise les sous-requêtes, les résultats sont vraiment corrects. Je n'aime pas utiliser des effets secondaires non documentés, qui peuvent changer d'une version à l'autre.