[分析]全体の問い合わせの原理原則説明&トレースMySQLの深さ分析のファジーインデックスを行きます

I.背景

今日では、交換基の1の生徒が疑問を提起しました。ルック:
ここに画像を挿入説明
:学生は本当にあいまい例のインデックスを取って完全な問い合わせをした後、
ここに画像を挿入説明
これまで我々は、これらの2つのSQLの最大の違いがあることがわかります(選択*)フルフィールドのクエリが、唯一のAクエリの主キー(選択ID)。

この時点で、他の学生は、他のプログラムについて話しましたがされています。
ここに画像を挿入説明
全文は、これは全体の問い合わせがあいまいインデックスを行かせること、言うまでもないインデックス作成します。しかし、このプログラムをカバーするインデックスが、私はそれが背景と一致していると思います:

一般的なインデックスが主キーのみをカバーするインデックスを過ごすことができ照会しながら1は、背景があるため、あいまいクエリフィールドの質問は、通常のインデックスです。

2、およびのみ主キークエリ(ID)は費用がインデックス表示される背景、。

第二に、データの準備やシーンを再現

1、準備テーブルとデータ:

ユーザーテーブルを作成し、通常の携帯電話のインデックスにフィールドを追加します。

CREATE TABLE `user` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `phone` varchar(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `index_phone` (`phone`) USING BTREE COMMENT 'phone索引'
) ENGINE=InnoDB AUTO_INCREMENT=200007 DEFAULT CHARSET=utf8;

100 000データの準備の意味の意味:

delimiter ;
CREATE DEFINER=`root`@`localhost` PROCEDURE `iniData`()
begin
  declare i int;
  set i=1;
  while(i<=100000)do
    insert into user(name,age,phone) values('测试', i, 15627230000+i);
    set i=i+1;
  end while;
end;;
delimiter ;

call iniData();

2、SQLの実装は、実行計画を表示します。

explain select * from user where phone like '%156%';
explain select id from user where phone like '%156%';

3.結果:

ID SELECT_TYPE テーブル パーティション タイプ possible_keys キー key_lenに REF フィルタ エクストラ
1 SIMPLE ユーザー すべて 99927 11.11 どこ使い方
ID SELECT_TYPE テーブル パーティション タイプ possible_keys キー key_lenに REF フィルタ エクストラ
1 SIMPLE ユーザー 指数 index_phone 36 99927 11.11 どこ使い方; インデックスを使用して

私たちは、2番目のSQLが実際に使用していた示していることがわかりますindex_phoneインデックスを。

しかし、注意してください学生は見つけることがあります。possible_keys実際には空であります!病気の感染。

私は関係prossible_keysとキーについて話すためにここにいます:

図1に示すように、possible_keysインデックスが使用されてもよく、key実際の使用の指標です。

図2に示すように、正常である:keyインデックスが必然的に含まれますpossible_keys

そこトリッキーなポイントは次のとおりです(行)を読んで、インデックスを使用せずに、インデックスと行数を使用するのと同じであることが判明!

第三に、検証段階と推測

前述した、possible_keyskeyの関係、そして我々はそれを確認するために、通常の撮影のインデックスを使用しています。

次のSQL、すべてではないあいまいクエリが、インデックスを取るの特定であることが保証権利あいまいクエリは、我々はこの時点で個別に見てpossible_keyskey値:

explain select id from user where phone like '156%';

結果:

ID SELECT_TYPE テーブル パーティション タイプ possible_keys キー key_lenに REF フィルタ エクストラ
1 SIMPLE ユーザー 範囲 index_phone index_phone 36 49963 100 どこ使い方; インデックスを使用して

ここではあまりにも明白:

1、possible_keysそれは含まれないkeyインデックスに。

2、およびrowsフルは倍増し、ダウン瞬時には、49963に低下したfiltered100に達しました。

ステージの推測:

1、まず第一に、select id from user where phone like '%156%';ので、カバーインデックスは、むしろインデックスを過ごしますindex_phone

2、possible_keysがnullの場合、木を見つけるために、インデックスへのアクセスを証明していません。明らかに、select id from user where phone like '%156%';表示が消えインデックスがあるにもかかわらず、しかし、行数の読み取りselect * from user where phone like '%156%';のインデックスはかかりませんでした行は同じです。

3、我々は、推測することが可能select id from user where phone like '%156%';であってもインデックスが使用していたカバーとしてのindex_phoneインデックスを、しかし過ごすためにツリー、インデックスツリーをトラバースするだけで、通常の順序を見つけることができませんでした。だから、実際には、SQLフィールドに2つの小さなテーブルは、クエリのパフォーマンスが勇気を召喚する必要があります。

トレース分析によって検証第四に、

私たちはどのように選択するかであるオプティマイザの両方のSQLのトレース解析を使用していました。

1、お問い合わせのフィールド全体:
-- 开启优化器跟踪
set session optimizer_trace='enabled=on';
select * from user where phone like '%156%';
-- 查看优化器追踪
select * from information_schema.optimizer_trace;

ここでは、ライン上でTRACEを見て:

{
  "steps": [
    {
      "join_preparation": {
        "select#": 1,
        "steps": [
          {
            "expanded_query": "/* select#1 */ select `user`.`id` AS `id`,`user`.`name` AS `name`,`user`.`age` AS `age`,`user`.`phone` AS `phone` from `user` where (`user`.`phone` like '%156%')"
          }
        ]
      }
    },
    {
      "join_optimization": {
        "select#": 1,
        "steps": [
          {
            "condition_processing": {
              "condition": "WHERE",
              "original_condition": "(`user`.`phone` like '%156%')",
              "steps": [
                {
                  "transformation": "equality_propagation",
                  "resulting_condition": "(`user`.`phone` like '%156%')"
                },
                {
                  "transformation": "constant_propagation",
                  "resulting_condition": "(`user`.`phone` like '%156%')"
                },
                {
                  "transformation": "trivial_condition_removal",
                  "resulting_condition": "(`user`.`phone` like '%156%')"
                }
              ]
            }
          },
          {
            "substitute_generated_columns": {
            }
          },
          {
            "table_dependencies": [
              {
                "table": "`user`",
                "row_may_be_null": false,
                "map_bit": 0,
                "depends_on_map_bits": [
                ]
              }
            ]
          },
          {
            "ref_optimizer_key_uses": [
            ]
          },
          {
            "rows_estimation": [
              {
                "table": "`user`",
                "table_scan": {
                  "rows": 99927,
                  "cost": 289
                }
              }
            ]
          },
          {
            "considered_execution_plans": [
              {
                "plan_prefix": [
                ],
                "table": "`user`",
                "best_access_path": {
                  "considered_access_paths": [
                    {
                      "rows_to_scan": 99927,
                      "access_type": "scan", // 顺序扫描
                      "resulting_rows": 99927,
                      "cost": 20274,
                      "chosen": true
                    }
                  ]
                },
                "condition_filtering_pct": 100,
                "rows_for_plan": 99927,
                "cost_for_plan": 20274,
                "chosen": true
              }
            ]
          },
          {
            "attaching_conditions_to_tables": {
              "original_condition": "(`user`.`phone` like '%156%')",
              "attached_conditions_computation": [
              ],
              "attached_conditions_summary": [
                {
                  "table": "`user`",
                  "attached": "(`user`.`phone` like '%156%')"
                }
              ]
            }
          },
          {
            "refine_plan": [
              {
                "table": "`user`"
              }
            ]
          }
        ]
      }
    },
    {
      "join_execution": {
        "select#": 1,
        "steps": [
        ]
      }
    }
  ]
}
2、主キーのみのクエリ
set session optimizer_trace='enabled=on';
select id from user where phone like '%156%';
-- 查看优化器追踪
select * from information_schema.optimizer_trace;

ここでは、ライン上でTRACEを探し続けて:

{
  "steps": [
    {
      "join_preparation": {
        "select#": 1,
        "steps": [
          {
            "expanded_query": "/* select#1 */ select `user`.`id` AS `id` from `user` where (`user`.`phone` like '%156%')"
          }
        ]
      }
    },
    {
      "join_optimization": {
        "select#": 1,
        "steps": [
          {
            "condition_processing": {
              "condition": "WHERE",
              "original_condition": "(`user`.`phone` like '%156%')",
              "steps": [
                {
                  "transformation": "equality_propagation",
                  "resulting_condition": "(`user`.`phone` like '%156%')"
                },
                {
                  "transformation": "constant_propagation",
                  "resulting_condition": "(`user`.`phone` like '%156%')"
                },
                {
                  "transformation": "trivial_condition_removal",
                  "resulting_condition": "(`user`.`phone` like '%156%')"
                }
              ]
            }
          },
          {
            "substitute_generated_columns": {
            }
          },
          {
            "table_dependencies": [
              {
                "table": "`user`",
                "row_may_be_null": false,
                "map_bit": 0,
                "depends_on_map_bits": [
                ]
              }
            ]
          },
          {
            "ref_optimizer_key_uses": [
            ]
          },
          {
            "rows_estimation": [
              {
                "table": "`user`",
                "table_scan": {
                  "rows": 99927,
                  "cost": 289
                }
              }
            ]
          },
          {
            "considered_execution_plans": [
              {
                "plan_prefix": [
                ],
                "table": "`user`",
                "best_access_path": {
                  "considered_access_paths": [
                    {
                      "rows_to_scan": 99927,
                      "access_type": "scan", // 顺序扫描
                      "resulting_rows": 99927,
                      "cost": 20274,
                      "chosen": true
                    }
                  ]
                },
                "condition_filtering_pct": 100,
                "rows_for_plan": 99927,
                "cost_for_plan": 20274,
                "chosen": true
              }
            ]
          },
          {
            "attaching_conditions_to_tables": {
              "original_condition": "(`user`.`phone` like '%156%')",
              "attached_conditions_computation": [
              ],
              "attached_conditions_summary": [
                {
                  "table": "`user`",
                  "attached": "(`user`.`phone` like '%156%')"
                }
              ]
            }
          },
          {
            "refine_plan": [
              {
                "table": "`user`"
              }
            ]
          }
        ]
      }
    },
    {
      "join_execution": {
        "select#": 1,
        "steps": [
        ]
      }
    }
  ]
}

さて、ここでは、両方のSQLのためにどのようなオプティマイザのインデックスの実際の選択を示さなかった、トレース内の解析、見つけることができますが、それだけのショーあなたが使用している順次走査データを見つけるために方法を。

他の全表スキャン通常のインデックスを使用している間、主キーインデックスを使用してスキャン全表;:おそらく唯一の違いは、それはあるが、2つはB +木の特性上無用である、見つけるためにツリーを費やすことはありませんでしたクエリのパフォーマンスを向上させます。

第六に、締結

図1に示すように、主キーとしてのみファジークエリ結果セットの完全なSQLクエリは、カバーインデックスので、インデックスがクエリのフィールドに対応する過ごすことになります。

2、インデックスが使用していたが、特性を過ごすために木が、トラバーサルの正常な秩序を見つけることができなかった場合でも。

図3に示すように、通常のフル・テーブル・スキャンは、実際には、両方の性能が実際には同じであるので、こと、トラバーサルの順序の主キーインデックスです。

おすすめ

転載: www.cnblogs.com/Howinfun/p/12449975.html