ホームページ  >  記事  >  データベース  >  Mysql でよくある SQL 使用上の 8 つのエラー

Mysql でよくある SQL 使用上の 8 つのエラー

王林
王林転載
2019-08-27 10:49:442589ブラウズ

はじめに

MySQL は、2016 年もデータベースの人気において力強い成長傾向を維持しました。 MySQL データベース上でアプリケーションを構築したり、Oracle から MySQL に移行したりする顧客が増えています。ただし、一部の顧客は、MySQL データベースの使用時に応答時間の遅さや CPU のフル使用率などの問題に遭遇することもあります。

Alibaba Cloud RDS エキスパート サービス チームは、クラウド顧客の多くの緊急問題の解決を支援してきました。 「ApsaraDB Expert Diagnostic Report」に表示される一般的な SQL の問題の一部を、参考までに以下にまとめます。

1. LIMIT ステートメント

ページング クエリは最も一般的に使用されるシナリオの 1 つですが、通常は最も問題が発生しやすいシナリオでもあります。

たとえば、次の単純なステートメントの場合、一般的な DBA のアイデアは、type、name、create_time フィールドに複合インデックスを追加することです。このように、条件付きソートはインデックスを有効に活用することができ、パフォーマンスを急速に向上させることができます。

SELECT *  FROM   operation  WHERE  type = 'SQLStats'         AND name = 'SlowLog'  ORDER  BY create_time  LIMIT  1000, 10;

そうですね、おそらく 90% 以上の DBA がこの問題を解決してそこで止まります。

しかし、LIMIT 句が「LIMIT 1000000,10」になっても、プログラマは依然として不満を抱くでしょう。「レコードを 10 件フェッチするだけなのに、なぜまだ遅いのですか?」

データベースは 1,000,000 番目のレコードがどこから始まるのかを認識していないため、インデックスがあっても最初から計算する必要があることを知っておく必要があります。この種のパフォーマンスの問題が発生する場合、ほとんどの場合、プログラマは怠惰です。フロントエンドのデータ閲覧やページめくり、ビッグデータの一括エクスポートなどのシナリオでは、前のページの最大値をクエリ条件のパラメータとして使用できます。 SQL は次のように再設計されています:

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. 暗黙的な変換

SQL ステートメント内のクエリ変数とフィールド定義の型の不一致も、よくあるエラーの 1 つです。たとえば、次のステートメント:

Mysql でよくある SQL 使用上の 8 つのエラー

フィールド bpn は varchar(20) として定義されています。MySQL の戦略は、比較する前に文字列を数値に変換することです。この関数はテーブルのフィールドに作用し、インデックスは無効になります。

上記の状況は、プログラマの本来の意図ではなく、アプリケーション フレームワークによって自動的にパラメータが入力された可能性があります。最近は非常に複雑なアプリケーションフレームワークが多く、使いやすい反面、穴を掘ってしまう可能性もあるので注意が必要です。

3. アソシエーションの更新と削除

MySQL5.6 では具体化機能が導入されていますが、現時点ではクエリ ステートメントに対してのみ最適化されているという事実に特別な注意を払う必要があります。 。更新または削除の場合は、手動で JOIN に書き換える必要があります。

たとえば、以下の UPDATE ステートメントでは、MySQL は実際にループ/ネストされたサブクエリ (DEPENDENT SUBQUERY) を実行しますが、その実行時間は想像できます。

Mysql でよくある SQL 使用上の 8 つのエラー

#実行計画:

Mysql でよくある SQL 使用上の 8 つのエラー

4. 混合ソート

MySQLインデックスは混合ソートには使用できません。ただし、一部のシナリオでは、パフォーマンスを向上させるために特別な方法を使用する機会がまだあります。

Mysql でよくある SQL 使用上の 8 つのエラー

実行プランはテーブル全体のスキャンとして表示されます。

Mysql でよくある SQL 使用上の 8 つのエラー

is_reply には 0 と 2 つの状態しかないため、 1、次のメソッドを書き換えたところ、実行時間が 1.58 秒から 2 ミリ秒に短縮されました。

Mysql でよくある SQL 使用上の 8 つのエラー

5、EXISTS语句

MySQL 对待 EXISTS 子句时,仍然采用嵌套子查询的执行方式。如下面的 SQL 语句:

Mysql でよくある SQL 使用上の 8 つのエラー

执行计划为:

Mysql でよくある SQL 使用上の 8 つのエラー

去掉 exists 更改为 join,能够避免嵌套子查询,将执行时间从1.93秒降低为1毫秒。

Mysql でよくある SQL 使用上の 8 つのエラー

新的执行计划:

Mysql でよくある SQL 使用上の 8 つのエラー

6、条件下推

外部查询条件不能够下推到复杂的视图或子查询的情况有:

聚合子查询;

含有 LIMIT 的子查询;

UNION 或 UNION ALL 子查询;

输出字段中的子查询;

如下面的语句,从执行计划可以看出其条件作用于聚合子查询之后:

Mysql でよくある SQL 使用上の 8 つのエラー

Mysql でよくある SQL 使用上の 8 つのエラー

确定从语义上查询条件可以直接下推后,重写如下:

SELECT target Count(*)  FROM   operation  WHERE  target = 'rm-xxxx'  GROUP  BY target

执行计划变为:

Mysql でよくある SQL 使用上の 8 つのエラー

关于 MySQL 外部条件不能下推的详细解释说明请参考文章:

http://mysql.taobao.org/monthly/2016/07/08

相了解更多相关问题请访问PHP中文网:mysql视频教程

以上がMysql でよくある SQL 使用上の 8 つのエラーの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcnblogs.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。