MySql SQL最適化のヒントの共有

MySql SQL最適化のヒントの共有

ある日、内部結合を含む SQL ステートメントの実行速度はそれほど遅くはない (0.1 ~ 0.2) ものの、理想的な速度には達していないことに気付きました。 2 つのテーブルは関連付けられており、関連付けられているフィールドは主キーであり、クエリされたフィールドは一意のインデックスです。

SQL は次のとおりです。

選択
p_item_token.*,
p_item.製品タイプ
から
p_item_token
p_item を p_item.itemid = p_item_token.itemid に内部結合します。
どこ
p_item_token.token = 'db87a780427d4d02ba2bd49fac8xxx';

テーブル p_item_token では、itemid が主キーであり、token が一意のインデックスです。 p_itemのitemidは主キーです

理想的な速度は0.03秒程度です。しかし、実際の値は約 0.2 であり、はるかに遅くなります。

計画を確認するには直接EXPLAINしてください

説明する
選択
  p_item_token.*,
  p_item.製品タイプ
から
  p_item_token
p_item を p_item.itemid = p_item_token.itemid に内部結合します。
どこ
  p_item_token.token = 'db87a780427d4d02ba2bd49fac8xxx';

結果:

上の大きな赤いボックスに注意してください。 p_item テーブルには 20,000 件のレコードがあるため、これは完全なテーブルスキャンになります。

それは普通じゃない。

警告を表示して確認します。注意: 場合によっては、SHOW WARNINGS が効果を持たないことがあります。理由はまだ分かりません。ローカル テスト データベースで実行することをお勧めします。

説明する
選択
  p_item_token.*,
  p_item.製品タイプ
から
  p_item_token
p_item を p_item.itemid = p_item_token.itemid に内部結合します。
どこ
  p_item_token.token = 'db87a780427d4d02ba2bd49fac8xxx';
警告を表示; 

結果 2 には code=1003 が表示されます。その背後には SQL ステートメントがあります。このステートメントは、入力した SQL ステートメントをルールに従って書き換えた後に MySQL によって実行される最終ステートメントです。

/* 選択#1 */
選択
  '0000eb612d78407a91a9b3854ffffffff' AS `itemid`, /*注: 値を見つけるには主キーを直接押します*/
  'db87a780427d4d02ba2bd49fac8cf98b' を `トークン` として、    
  '2016-12-16 10:46:53' として `create_time`、        
  '' AS `ftoken`、                    
  `p_db`.`p_item`.`product_type` を `product_type` として  
から
  `p_db`.`p_item_token`
`p_db`.`p_item` を結合します
どこ
  (
    (
      変換する (
        `p_db`.`p_item`.`itemid` utf8mb4 を使用
      ) = '0000eb612d78407a91a9b3854fffffff'
    )
  )

それは奇妙ですね。 Where に CONVERT があるのはなぜですか? where 条件の式の左側、つまりクエリ対象のフィールドに関数がある場合、速度低下の原因になることがわかっています。 (私の理解では、インデックスが使用されていないため遅くなります。インデックスの値は元の値ですが、この条件で使用される値は処理された値です。)

この関数は、itemid 列のエンコーディングを utf8mb4 に変換することに注意してください。つまり、この列のエンコーディングは utf8mb4 ではありません。

テーブルを開き、両方のテーブルの itemid 列のエンコーディングを utf8 に変更します。説明をもう一度実行します。

結果を説明することに問題はありません。

結果 2 のステートメントを見てください。

/* 選択#1 */
選択
  '0000eb612d78407a91a9b3854fffffff' として `itemid`、
  'db87a780427d4d02ba2bd49fac8cf98b' を `トークン` として、
  '2016-12-16 10:46:53' として `create_time`、
  '' AS `ftoken`、
  'cxx' を `product_type` として
から
  `toy_item_plat`.`p_item_token`
`toy_item_plat`.`p_item` を結合します
どこ
  1

この選択には定数がいっぱいあります。どうして遅いのでしょうか?

実行結果: 0.036秒。期待に応える

学んだ教訓:

Explain は、実行プランが期待どおりかどうかを確認できます。大きな行がある場合は、完全なテーブルスキャンが発生したことを意味し、将来的にパフォーマンスのボトルネックになります。

show warning コマンドを使用すると、オプティマイザーによって処理されたステートメントを確認できます。元の記述と矛盾がある場合は、慎重に比較して検討することで実際の問題が明らかになることがあります。

以下もご興味があるかもしれません:
  • MySQL 5.7.20 共通ダウンロード、インストール、設定方法と簡単な操作スキル(解凍版無料インストール)
  • Java Web を使用して MySQL データベースに接続する方法
  • tcpdump を使用して mysql のパケットをキャプチャする方法
  • MySQL数千万の大規模データに対する30のSQLクエリ最適化テクニックの詳細な説明
  • 時間に基づいて日付をクエリするためのMySQL最適化テクニック
  • MYSQL クエリの効率を向上させる 10 の SQL ステートメント最適化テクニック
  • MySQL クイックデータ比較テクニック
  • MySQL の一般的な問題とアプリケーション スキルの概要
  • MySQL データ ウェアハウスを保護するための 5 つのヒント
  • MySQL のデバッグと最適化に関する 101 のヒントを共有する
  • MySQLインジェクションバイパスフィルタリング技術の概要
  • MySQLデータベースの共通操作スキルのまとめ

<<:  Vue イベントの $event パラメータ = イベント値の場合

>>:  Linux システムのスワップ領域の紹介

推薦する

Ubuntu で FTP サーバーを構築する方法の詳細な説明 (成功保証)

1. 今日の午後、コースの要件により、Ubuntu で FTP サーバーを設定する実験を行う必要が...

Dockerはプライベートライブラリイメージを完全に削除します

まず、インターネット上の一般的な慣行を見てみましょうデフォルトでは、プライベート ライブラリはイメー...

MySQL 文字セットの表示と変更のチュートリアル

1. 文字セットを確認する1. MYSQLデータベースサーバーとデータベースの文字セットを確認する方...

HTML+CSSで充電水滴融合特殊効果コードを実現

目次序文:成し遂げる:要約:まず効果を見てみましょう: 序文:このアイデアは、Bilibili のア...

1 つの記事で Vue ミドルウェア パイプラインを学ぶ

SPA を構築する場合、多くの場合、特定のルートを保護する必要があります。たとえば、認証されたユーザ...

CSS スティッキーフッタークラシックレイアウトの実装

スティッキーフッターレイアウトとは何ですか?一般的な Web ページのレイアウトは、通常、ヘッダー部...

Web ページ WB.ExecWB 制御印刷メソッド呼び出しの説明とパラメータの紹介

WebページWB.ExecWB制御印刷方法コードをコピーコードは次のとおりです。 <テーブルの...

jQueryは何に使われるのですか?jQueryは実際にはjsフレームワークです

jQuery 入門jQuery ライブラリは、簡単なマークアップ行を使用して Web ページに追加で...

Tomcat の maxPostSize 設定に関する問題と注意事項

1. maxPostSize を設定する理由は何ですか? tomcat コンテナには送信データのサイ...

CSS3 変換によって子要素の固定位置を絶対位置に変更する方法

この記事では、CSS3 の transform を使用して子要素の固定配置を絶対配置に変更する方法を...

Tomcatアーキテクチャの原則をアーキテクチャ設計に分析する

目次1. 学習目標1.1. Tomcatアーキテクチャの設計と原則をマスターして社内スキルを向上させ...

枠線や境界線のない iframe を使用するための完全ガイド (実践経験のまとめ)

<iframe src=”ページのURL” width=”100″ height=”30″ f...

MySQL 8.0 のタイムゾーン問題を解決する手順

ソフトウェアバージョンウィンドウズ: ウィンドウズ10 MySQL: mysql-8.0.16-wi...

MySQLの外部結合と内部結合クエリの違い

外部結合の構文は次のとおりです。フィールド名を選択FROM テーブル名 1 LEFT|RIGHT|F...

Vue3 ベースのフルスクリーン ドラッグ アップロード コンポーネント

この記事は主に、みんなで共有できるVue3ベースのフルスクリーンドラッグアップロードコンポーネントを...