web-dev-qa-db-fra.com

Quelle est la différence de performance entre dans (42) et ID = 42 dans MySQL?

Y a-t-il des différences de performance entre

SELECT * 
FROM table 
WHERE id IN (42);

et

SELECT * 
FROM table 
WHERE id = 42;

?

La question concerne simplement une seule valeur. L'hypothèse naturelle pour moi est que l'optimiseur les traitera comme étant égale et effectuera la même optimisation lors de la récupération des données. Mais est-ce correct?

5
Jan Seevers

Si les requêtes sont équivalentes ou non à l'optimiseur de la requête MySQL. Pourquoi ?

Retour N Mar, 13 2013 J'ai écrit une réponse à ce message: Y a-t-il une différence d'exécution entre une condition de jointure et une condition?

Dans ce poste, j'ai décrit exactement comment les jointures sont exécutées. Ce qui suit est extrait de mon message qui citait - Page 172 de compréhension MySQL Internals :

  • Déterminez quelles clés peuvent être utilisées pour récupérer les enregistrements des tables et choisir le meilleur pour chaque table.
  • Pour chaque table, décidez si une analyse de table est meilleure que la lecture sur une clé. S'il y a beaucoup d'enregistrements correspondant à la valeur clé, les avantages de la clé sont réduits et la numérisation de la table devient plus rapide.
  • Déterminez l'ordre dans lequel les tableaux doivent être joints lorsque plusieurs tables sont présentes dans la requête.
  • Réécrivez les clauses pour éliminer le code mort, réduisant les calculs inutiles et modifier les contraintes dans la mesure du possible à l'ouverture de la voie à l'utilisation des touches.
  • Éliminez les tables non utilisées de la jointure.
  • Déterminez si les touches peuvent être utilisées pour ORDER BY Et GROUP BY.
  • Essayez de simplifier les sous-sollicitations, ainsi que de déterminer dans quelle mesure leurs résultats peuvent être mis en cache.
  • Fusionner des vues (élargir la référence de vue en tant que macro)

Sur cette même page, il dit ce qui suit:

Dans la terminologie Optimizer MySQL, chaque requête est un ensemble de jointures. Le terme rejoindre est utilisé ici plus largement que dans les commandes SQL. Une requête sur une seule table est une jointure dégénérée. Bien que nous ne pensons normalement pas de lire des enregistrements d'une table en tant que jointure, les mêmes structures et algorithmes utilisés avec des jointures conventionnelles fonctionnent parfaitement pour résoudre la requête avec une seule table.

À partir des informations susmentionnées, le comportement des joints s'exécutera le même indique quelles que soient une requête présentant plusieurs tables ou événement d'une seule table.

Votre question initiale

Sous la hotte, MySQL évaluera les deux requêtes de la même manière. Si vous voulez de meilleures performances de la requête, vous devez prendre le taureau par les cornes. Vous devriez faire tout ce que vous pouvez sur la table afin que MySQL rejoindre le comportement soit aussi lisse que possible.

  • Ajouter les index nécessaires
  • Augmenter les tampons de niveau de session (tri_buffer_size, join_buffer_size)
  • Profitez des mécanismes de stockage des moteurs pour la réglage des données et des index
  • Refacteur la requête

Si vous regardez Réponse de Dimitar , il époque maintenant un cas où le comportement de la jointure de MySQL est mis à l'épreuve. Au lieu de parier sur deux chevaux que vous possédez (vos questions) pour voir qui fonctionne mieux, investissez du temps à obtenir un cheval plus rapide si un tel cheval existe.

De la poste de Ditimar, vous avez ces

  • SELECT * FROM table WHERE id IN (42,43,44,45);
  • SELECT * FROM table WHERE id = 42 or id = 43 or id = 44 or id = 45;

Voici encore un autre que je suggère pour l'exemple de l'exemple

SELECT A.* FROM table A INNER JOIN
(SELECT 42 id UNION SELECT 43 UNION SELECT 44 UNION SELECT 45) B
USING (id);

et un autre

SELECT * FROM table WHERE id = 42
UNION
SELECT * FROM table WHERE id = 43
UNION
SELECT * FROM table WHERE id = 44
UNION
SELECT * FROM table WHERE id = 45;

Je peux constituer d'autres possibilités, mais l'idée principale ici est d'essayer d'écrire de bonnes requêtes la première fois. Lorsque votre quantité de données augmente, vos meilleures requêtes peuvent souffrir de la distribution clés et des statistiques d'index obsolètes qui peuvent nécessiter une optimisation des tables ou même une réécriture des requêtes pour convenir à des données plus grandes.

3
RolandoMySQLDBA
SELECT * FROM table WHERE id IN (42,43,44,45,...);

est équivalent à

SELECT * FROM table WHERE id = 42 or id = 43 or id = 44 or id  = ...;
1
dimitar