Les administrateurs de base de données ou les développeurs qui ont utilisé Oracle ou d'autres bases de données relationnelles ont cette expérience. Ils pensent tous que la base de données a été optimisée pour les sous-requêtes et peuvent choisir de bien piloter l'exécution des tables, puis transplanter cette expérience vers MySQL sur la base de données. mais malheureusement, MySQL risque de vous décevoir dans le traitement des sous-requêtes. Nous avons rencontré ce problème sur notre système de production :
select i_id, sum(i_sell) as i_sell from table_data where i_id in (select i_id from table_data where Gmt_create >= ‘2011-10-07 00:00:00’) group by i_id;
(Remarque : SQL business La logique peut être utilisée comme analogie : interrogez d'abord les 100 livres. nouvellement vendus le 10-07, puis interrogez les ventes de ces 100 livres nouvellement vendus tout au long de l'année).
La raison pour laquelle le problème de performances de ce SQL est la faiblesse de l'optimiseur mysql dans le traitement des sous-requêtes. Lorsque l'optimiseur mysql traite la sous-requête, il réécrit la sous-requête. Normalement, nous espérons d'abord compléter les résultats de la sous-requête de l'intérieur vers l'extérieur, puis utiliser la sous-requête pour piloter la table de requête externe afin de terminer la requête. Cependant, le traitement MySQL analysera d'abord toutes les données de la table externe ; et chaque Les données seront transférées à la sous-requête et associées à la sous-requête. Si l'apparence est très volumineuse, il y aura des problèmes de performances
Pour la requête ci-dessus, puisque les données de la table table_data ont 70W ; data, En même temps, il y a beaucoup de données dans la sous-requête, et une grande partie est répétée, ce qui nécessite près de 700 000 corrélations, ce qui fait que ce sql s'exécute pendant plusieurs heures sans être terminé, nous devons donc réécrire le SQL :
SELECT t2.i_id, SUM(t2.i_sell) AS sold FROM (SELECT distinct i_id FROM table_data WHERE gmt_create >= ‘2011-10-07 00:00:00’) t1, table_data t2 WHERE t1.i_id = t2.i_id GROUP BY t2.i_id;
Nous avons changé la sous-requête en association et ajouté distinct à la sous-requête pour réduire le nombre de fois que t1 est associé à t2
Après le ; transformation, le temps d’exécution de SQL a été réduit à moins de 100 ms.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!