MySql の詳細な紹介 SQL 最適化スキルの共有

黄舟
リリース: 2017-03-24 13:49:37
オリジナル
1288 人が閲覧しました

この記事は主に MySql SQL 最適化スキルの共有を紹介します。これは非常に優れており、参考価値があります。必要な友人はそれを参照できます

ある日、実行速度はそれほど遅いわけではありませんが、内部結合を備えた SQL を見つけました。 (0.1-0.2 ) ですが、理想的な速度には達していません。 2 つのテーブルは関連しており、関連フィールドは主キー、クエリされたフィールドは一意のインデックスです。

sql は次のとおりです:

SELECT
p_item_token.*,
p_item.product_type
FROM
p_item_token
INNER JOIN p_item ON p_item.itemid = p_item_token.itemid
WHERE
p_item_token.token ='db87a780427d4d02ba2bd49fac8xxx';
ログイン後にコピー

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

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

直接説明してプランを確認してください

EXPLAIN
SELECT
  p_item_token.*,
  p_item.product_type
FROM
  p_item_token
INNER JOIN p_item ON p_item.itemid = p_item_token.itemid
WHERE
  p_item_token.token = 'db87a780427d4d02ba2bd49fac8xxx';
ログイン後にコピー

結果:

MySql の詳細な紹介 SQL 最適化スキルの共有

上の大きな赤いボックスに注目してください。 p_item テーブルには 2w 個のデータがあるため、これはテーブル全体のスキャンになります。

普通じゃないよ。

ショーの警告を追加して見てください。注: 場合によっては、SHOW WARNINGS では結果が得られません。理由はまだわかりません。ローカルのテスト データベースで実行することをお勧めします。

EXPLAIN
SELECT
  p_item_token.*,
  p_item.product_type
FROM
  p_item_token
INNER JOIN p_item ON p_item.itemid = p_item_token.itemid
WHERE
  p_item_token.token = 'db87a780427d4d02ba2bd49fac8xxx';
SHOW WARNINGS;
ログイン後にコピー

MySql の詳細な紹介 SQL 最適化スキルの共有

結果 2 には、コード = 1003 が含まれています。このステートメントは、入力した SQL ステートメントをルールに従って書き換えた後、MySQL によって実行される最後のステートメントです。

そうです

それは奇妙です。なぜどこに CONVERT があるのでしょうか? where 条件、つまりクエリ対象のフィールドの方程式の左側に 関数 がある場合、速度が遅くなることがわかっています。 (私の理解: 参照が取得できないので遅いです。インデックスの値は元の値ですが、この条件では加工された値が使用されます。)

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

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

MySql の詳細な紹介 SQL 最適化スキルの共有

解釈結果から判断すると問題ありません。

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

/* select#1 */
SELECT
  '0000eb612d78407a91a9b3854ffffffff' AS `itemid`,    /*注:直接按主键把值查出来了*/
  'db87a780427d4d02ba2bd49fac8cf98b' AS `token`,    
  '2016-12-16 10:46:53' AS `create_time`,        
  '' AS `ftoken`,                    
  `p_db`.`p_item`.`product_type` AS `product_type`  
FROM
  `p_db`.`p_item_token`
JOIN `p_db`.`p_item`
WHERE
  (
    (
      CONVERT (
        `p_db`.`p_item`.`itemid` USING utf8mb4
      ) = '0000eb612d78407a91a9b3854fffffff'
    )
  )
ログイン後にコピー

この選択はすべて定数です。もっと速くできるでしょうか?

実行結果0.036秒。期待通りです

エクスペリエンスの概要:

説明 行が大きい場合は、フルテーブルスキャンが発生したことを意味し、将来的にパフォーマンスのボトルネックになることがわかります。オプティマイザによって処理されたステートメントに対する show warning の結果。元の記述と矛盾がある場合は、注意深く比較および検討することで実際の問題が明らかになることがあります。

以上がMySql の詳細な紹介 SQL 最適化スキルの共有の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート