当前位置:网站首页>An example of SQL trace in MySQL

An example of SQL trace in MySQL

2022-07-28 10:38:00 Two dogs don't run

Today, my colleague came over and asked sql Related issues . Why? select In the query conditions 2 Columns , It's on the watch 2 Single column index , It executes one of the indexes it plans to walk ,MySQL Is there any basis for it to do so ?

This problem , We can use mysql Of trace Function analysis .

trace Analyze how the optimizer chooses the execution plan , The disadvantage of this method is that you must actually run this once SQL To get the analysis results

Case study :

CREATE TABLE `tb1` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`o_no` varchar(32) NOT NULL,
`status` char(4) NOT NULL ,
`p_id` bigint(20) DEFAULT NULL ,
`p_name` varchar(64) DEFAULT NULL ,
`pay_time` varchar(64) DEFAULT NULL ,
`create_time` varchar(64) DEFAULT NULL ,
PRIMARY KEY (`id`),
KEY `key_o_no_status` (`o_no`,`status`),
KEY `idx_create_time` (`create_time`),
KEY `idx_p_name` (`p_name`),
KEY `idx_pay_time` (`pay_time`),
KEY `idx_p_id` (`p_id`)
) ENGINE=InnoDB ;


SQL:
SELECT * FROM db1.tb1 WHERE p_id = 11 AND p_name = ' Zhang Fei ' limit 0,1000 ;

Turn on trace:

SET OPTIMIZER_TRACE="enabled=on";
SET optimizer_trace_max_mem_size=1000000;

--  Actually execute this query sql
SELECT * FROM db1.tb1 WHERE p_id = 11 AND p_name = ' Zhang Fei ' limit 0,1000 ;

--  look down trace Result 
SELECT * FROM information_schema.optimizer_trace \G

 give the result as follows , I have made some simple remarks .

{
    "steps": [
      {
        "join_preparation": {
          "select#": 1,
          "steps": [
            {
              "expanded_query": "/* select#1 */ select  Here's the code  from `tb1` where ((`tb1`.`p_id` = 11) and (`tb1`.`p_name` = ' Zhang Fei ')) limit 0,1000"
            }
          ]
        }
      },
      {
        "join_optimization": {
          "select#": 1,
          "steps": [
            {
              "condition_processing": {
                "condition": "WHERE",
                "original_condition": "((`tb1`.`p_id` = 11) and (`tb1`.`p_name` = ' Zhang Fei '))",
                "steps": [
                  {
                    "transformation": "equality_propagation",
                    "resulting_condition": "((`tb1`.`p_name` = ' Zhang Fei ') and multiple equal(11, `tb1`.`p_id`))"
                  },
                  {
                    "transformation": "constant_propagation",
                    "resulting_condition": "((`tb1`.`p_name` = ' Zhang Fei ') and multiple equal(11, `tb1`.`p_id`))"
                  },
                  {
                    "transformation": "trivial_condition_removal",
                    "resulting_condition": "((`tb1`.`p_name` = ' Zhang Fei ') and multiple equal(11, `tb1`.`p_id`))"
                  }
                ]
              }
            },
            {
              "table_dependencies": [
                {
                  "table": "`tb1`",
                  "row_may_be_null": false,
                  "map_bit": 0,
                  "depends_on_map_bits": [
                  ]
                }
              ]
            },
            {
              "ref_optimizer_key_uses": [
                {
                  "table": "`tb1`",
                  "field": "p_name",
                  "equals": "' Zhang Fei '",
                  "null_rejecting": false
                },
                {
                  "table": "`tb1`",
                  "field": "p_id",
                  "equals": "11",
                  "null_rejecting": false
                }
              ]
            },
            {
              "rows_estimation": [
                {
                  "table": "`tb1`",
                  "range_analysis": {
                    "table_scan": {
                      "rows": 25450,
                      "cost": 30542
                    },
                    "potential_range_indices": [
                      {
                        "index": "PRIMARY",
                        "usable": false,
                        "cause": "not_applicable"
                      },
                      {
                        "index": "key_o_no_status",
                        "usable": false,
                        "cause": "not_applicable"
                      },
                      {
                        "index": "idx_create_time",
                        "usable": false,
                        "cause": "not_applicable"
                      },
                      {
                        "index": "idx_p_name",
                        "usable": true,     --->  This index is optional 
                        "key_parts": [
                          "p_name",
                          "id"
                        ]
                      },
                      {
                        "index": "idx_pay_time",
                        "usable": false,
                        "cause": "not_applicable"
                      },
                      {
                        "index": "idx_p_id",
                        "usable": true,    --->  This index is optional 
                        "key_parts": [
                          "p_id",
                          "id"
                        ]
                      }
                    ],
                    "setup_range_conditions": [
                    ],
                    "group_index_range": {
                      "chosen": false,
                      "cause": "not_group_by_or_distinct"
                    },
                    "analyzing_range_alternatives": {
                      "range_scan_alternatives": [
                        {
                          "index": "idx_p_name",
                          "ranges": [
                            " Zhang Fei  <= p_name <=  Zhang Fei "
                          ],
                          "index_dives_for_eq_ranges": true,
                          "rowid_ordered": true,
                          "using_mrr": false,
                          "index_only": false,
                          "rows": 45,
                          "cost": 55.01,    --->  Notice the cost
                          "chosen": true
                        },
                        {
                          "index": "idx_p_id",
                          "ranges": [
                            "11 <= p_id <= 11"
                          ],
                          "index_dives_for_eq_ranges": true,
                          "rowid_ordered": true,
                          "using_mrr": false,
                          "index_only": false,
                          "rows": 1,
                          "cost": 2.21,      --->  Notice the cost
                          "chosen": true
                        }
                      ],
                      "analyzing_roworder_intersect": {
                        "intersecting_indices": [
                          {
                            "index": "idx_p_id",
                            "index_scan_cost": 1,
                            "cumulated_index_scan_cost": 1,
                            "disk_sweep_cost": 0,
                            "cumulated_total_cost": 1,
                            "usable": true,  
                            "matching_rows_now": 1,
                            "isect_covering_with_this_index": false,
                            "chosen": true         ---> 
                          },
                          {
                            "index": "idx_p_name",
                            "index_scan_cost": 2.0732,
                            "cumulated_index_scan_cost": 3.0732,
                            "disk_sweep_cost": 0,
                            "cumulated_total_cost": 3.0732,
                            "usable": true,
                            "matching_rows_now": 0.0018,
                            "isect_covering_with_this_index": false,
                            "chosen": false,
                            "cause": "does_not_reduce_cost"
                          }
                        ],
                        "clustered_pk": {
                          "clustered_pk_added_to_intersect": false,
                          "cause": "no_clustered_pk_index"
                        },
                        "chosen": false,
                        "cause": "too_few_indexes_to_merge"
                      }
                    },
                    "chosen_range_access_summary": {
                      "range_access_plan": {
                        "type": "range_scan",
                        "index": "idx_p_id",
                        "rows": 1,
                        "ranges": [
                          "11 <= p_id <= 11"
                        ]
                      },
                      "rows_for_plan": 1,
                      "cost_for_plan": 2.21,
                      "chosen": true        ---> 
                    }
                  }
                }
              ]
            },
            {
              "considered_execution_plans": [   --->  Evaluate the optimal path 
                {
                  "plan_prefix": [
                  ],
                  "table": "`tb1`",
                  "best_access_path": {
                    "considered_access_paths": [
                      {
                        "access_type": "ref",
                        "index": "idx_p_name",
                        "rows": 45,
                        "cost": 54,
                        "chosen": true  --->  Alternative execution plan 1
                      },
                      {
                        "access_type": "ref",
                        "index": "idx_p_id",
                        "rows": 1,
                        "cost": 1.2,
                        "chosen": true  --->  Alternative execution plan 2
                      },
                      {
                        "access_type": "range",
                        "cause": "heuristic_index_cheaper",
                        "chosen": false
                      }
                    ]
                  },
                  "cost_for_plan": 1.2,    --->  Finally, I chose  " Alternative execution plan 2" , idx_p_id  This index , Because of its cost Minimum !
                  "rows_for_plan": 1,
                  "chosen": true
                }
              ]
            },
            {
              "attaching_conditions_to_tables": {
                "original_condition": "((`tb1`.`p_id` = 11) and (`tb1`.`p_name` = ' Zhang Fei '))",
                "attached_conditions_computation": [
                ],
                "attached_conditions_summary": [
                  {
                    "table": "`tb1`",
                    "attached": "(`tb1`.`p_name` = ' Zhang Fei ')"
                  }
                ]
              }
            },
            {
              "refine_plan": [
                {
                  "table": "`tb1`"
                }
              ]
            }
          ]
        }
      },
      {
        "join_execution": {
          "select#": 1,
          "steps": [
          ]
        }
      }
    ]
  }

You can see ,mysql Analyzed each possibility , I chose cost Lowest access_path( At least it thinks this is an optimal solution ).

It should be noted that , If the metadata information is not accurate , It will also affect the judgment of the implementation plan .

Sometimes the execution plan is too poor , We can do it artificially once analyze table, In addition, it can also be increased innodb_stats_persistent_sample_pages value ( From default 20 To adjust to 64), This parameter indicates analyze table to update Cardinality Value, the number of pages to be sampled each time . Increase this value , It can improve the accuracy of statistical information , It can also improve the accuracy of the implementation plan , But it has also increased accordingly analyze table Time for , It will also increase in InnoDB Analyzed on the table I/O expenses .

原网站

版权声明
本文为[Two dogs don't run]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/209/202207280958249200.html