Avant-propos
MySQL a toujours maintenu une forte tendance à la croissance de la popularité des bases de données en 2016. De plus en plus de clients construisent leurs applications sur la base de données MySQL, voire migrent d'Oracle vers MySQL. Cependant, certains clients rencontrent également des problèmes tels qu'un temps de réponse lent et une utilisation complète du processeur lors de l'utilisation de la base de données MySQL.
L'équipe de services experts d'Alibaba Cloud RDS a aidé les clients du cloud à résoudre de nombreux problèmes d'urgence. Certains problèmes SQL courants qui apparaissent dans le « Rapport de diagnostic expert ApsaraDB » sont résumés comme suit à titre de référence.
1. Instruction LIMIT
La requête de pagination est l'un des scénarios les plus couramment utilisés, mais c'est aussi généralement le plus sujet aux problèmes.
Par exemple, pour l'instruction simple suivante, l'idée générale du DBA est d'ajouter un index combiné sur les champs type, name et create_time. De cette manière, le tri conditionnel peut utiliser efficacement l’index et les performances peuvent être améliorées rapidement.
SELECT * FROM operation WHERE type = 'SQLStats' AND name = 'SlowLog' ORDER BY create_time LIMIT 1000, 10;
Eh bien, peut-être que plus de 90 % des administrateurs de base de données résolvent ce problème et s'arrêtent là.
Mais lorsque la clause LIMIT devient "LIMIT 1000000,10", les programmeurs se plaindront toujours : pourquoi est-ce toujours lent si je ne récupère que 10 enregistrements ?
Il faut savoir que la base de données ne sait pas où commence le 1 000 000ème enregistrement Même s'il existe un index, il faut le calculer depuis le début. Lorsque ce type de problème de performances se produit, dans la plupart des cas, le programmeur est paresseux. Dans des scénarios tels que la navigation dans les données frontales et le changement de page, ou l'exportation de Big Data par lots, la valeur maximale de la page précédente peut être utilisée comme paramètre en tant que condition de requête. SQL est repensé comme suit :
SELECT * FROM operation WHERE type = 'SQLStats' AND name = 'SlowLog' AND create_time > '2017-03-16 14:00:00' ORDER BY create_time limit 10;
2. Conversion implicite
L'inadéquation entre la variable de requête et les types de définition de champ dans les instructions SQL est une autre erreur courante. Par exemple, l'instruction suivante :
Le champ bpn est défini comme varchar(20). La stratégie de MySQL est de convertir la chaîne en nombre avant de comparer. La fonction agit sur les champs de la table et l'index devient invalide.
La situation ci-dessus peut être due aux paramètres automatiquement renseignés par le framework d'application, plutôt qu'à l'intention initiale du programmeur. De nos jours, il existe de nombreux frameworks d'applications très compliqués. Même s'ils sont faciles à utiliser, soyez prudent car ils peuvent creuser des trous pour vous.
3. Mise à jour, suppression de l'association
Bien que MySQL5.6 introduise la fonctionnalité de matérialisation, une attention particulière doit être portée au fait qu'elle n'est actuellement optimisée que pour les instructions de requête. . Pour les mises à jour ou les suppressions, vous devez le réécrire manuellement en tant que JOIN.
Par exemple, dans l'instruction UPDATE ci-dessous, MySQL exécute en fait une sous-requête en boucle/imbriquée (DEPENDENT SUBQUERY), et son temps d'exécution peut être imaginé.
Plan d'exécution :
Tri mixte
MySQL Les index ne peuvent pas être utilisés pour le tri mixte. Mais dans certains scénarios, il est encore possible d’utiliser des méthodes spéciales pour améliorer les performances.
Le plan d'exécution est affiché sous forme d'analyse de table complète :
Puisque is_reply n'a que deux états : 0 et 1, nous suivons Après la réécriture de la méthode suivante, le temps d'exécution a été réduit de 1,58 secondes à 2 millisecondes.
5、EXISTS语句
MySQL 对待 EXISTS 子句时,仍然采用嵌套子查询的执行方式。如下面的 SQL 语句:
执行计划为:
去掉 exists 更改为 join,能够避免嵌套子查询,将执行时间从1.93秒降低为1毫秒。
新的执行计划:
6、条件下推
外部查询条件不能够下推到复杂的视图或子查询的情况有:
聚合子查询;
含有 LIMIT 的子查询;
UNION 或 UNION ALL 子查询;
输出字段中的子查询;
如下面的语句,从执行计划可以看出其条件作用于聚合子查询之后:
确定从语义上查询条件可以直接下推后,重写如下:
SELECT target Count(*) FROM operation WHERE target = 'rm-xxxx' GROUP BY target
执行计划变为:
关于 MySQL 外部条件不能下推的详细解释说明请参考文章:
http://mysql.taobao.org/monthly/2016/07/08
相了解更多相关问题请访问PHP中文网:mysql视频教程
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!