mysql的trace跟蹤


root@D0DCS 15:17:24 [jing]> show create table t1\G;
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `c1` int(11) NOT NULL DEFAULT '0',
  `c2` varchar(128) DEFAULT NULL,
  `c3` varchar(64) DEFAULT NULL,
  `c4` int(11) DEFAULT NULL,
  PRIMARY KEY (`c1`),
  KEY `ind_c2` (`c2`),
  KEY `ind_c4` (`c4`),
  KEY `ind_c2_c4` (`c2`,`c4`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)


ERROR: 
No query specified


root@D0DCS 15:17:30 [jing]> select * from t1;
+----+------+------+------+
| c1 | c2   | c3   | c4   |
+----+------+------+------+
|  1 | a    | A    |   10 |
|  2 | b    | B    |   20 |
|  3 | b    | BB   |   20 |
|  4 | b    | BBB  |   30 |
|  5 | b    | BBB  |   40 |
|  6 | c    | C    |   50 |
|  7 | d    | D    |   60 |
+----+------+------+------+
7 rows in set (0.00 sec)






#打開profiling 的設置  
SET profiling = 1;  
SHOW VARIABLES LIKE '%profiling%';  
  
#查看隊列的內容  
show profiles;    
#來查看統計信息  
show profile block io,cpu for query 3;  




root@D0DCS 14:46:31 [jing]> explain select * from t1 where  c2='b' and c4=20;
+----+-------------+-------+------+-------------------------+--------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys           | key    | key_len | ref   | rows | Extra       |
+----+-------------+-------+------+-------------------------+--------+---------+-------+------+-------------+
|  1 | SIMPLE      | t1    | ref  | ind_c2,ind_c4,ind_c2_c4 | ind_c4 | 5       | const |    2 | Using where |
+----+-------------+-------+------+-------------------------+--------+---------+-------+------+-------------+
1 row in set (0.00 sec)






查看查看OPTIMIZER_TRACE方法:
set optimizer_trace="enabled=on"; 
set optimizer_trace_max_mem_size=1000000;




root@D0DCS 14:47:12 [jing]>   set end_markers_in_json=on;  
Query OK, 0 rows affected (0.00 sec)


root@D0DCS 14:55:15 [jing]> explain select * from t1 where  c2='b' and c4=20;
+----+-------------+-------+------+-------------------------+--------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys           | key    | key_len | ref   | rows | Extra       |
+----+-------------+-------+------+-------------------------+--------+---------+-------+------+-------------+
|  1 | SIMPLE      | t1    | ref  | ind_c2,ind_c4,ind_c2_c4 | ind_c4 | 5       | const |    2 | Using where |
+----+-------------+-------+------+-------------------------+--------+---------+-------+------+-------------+
1 row in set (0.00 sec)


root@D0DCS 14:55:44 [jing]> select * from information_schema.optimizer_trace\G;
*************************** 1. row ***************************
                            QUERY: explain select * from t1 where  c2='b' and c4=20
                            TRACE: {
  "steps": [
    {
      "join_preparation": {   ---優化準備工作
        "select#": 1,
        "steps": [
          {
            "expanded_query": "/* select#1 */ select `t1`.`c1` AS `c1`,`t1`.`c2` AS `c2`,`t1`.`c3` AS `c3`,`t1`.`c4` AS `c4` from `t1` where ((`t1`.`c2` = 'b') and (`t1`.`c4` = 20))"
          }
        ] /* steps */
      } /* join_preparation */
    },
    {
      "join_optimization": {  ---優化工作的主要階段,包括邏輯優化和物理優化兩個階段
        "select#": 1,
        "steps": [   ---優化工作的主要階段,邏輯優化階段
          {
            "condition_processing": {  ---邏輯優化,條件化簡
              "condition": "WHERE",
              "original_condition": "((`t1`.`c2` = 'b') and (`t1`.`c4` = 20))",
              "steps": [
                {
                  "transformation": "equality_propagation",   --邏輯優化,條件化簡,等式處理
                  "resulting_condition": "((`t1`.`c2` = 'b') and multiple equal(20, `t1`.`c4`))"
                },
                {
                  "transformation": "constant_propagation",   --邏輯優化,條件化簡,常量處理
                  "resulting_condition": "((`t1`.`c2` = 'b') and multiple equal(20, `t1`.`c4`))"
                },
                {
                  "transformation": "trivial_condition_removal",  --邏輯優化,條件化簡,條件去除
                  "resulting_condition": "((`t1`.`c2` = 'b') and multiple equal(20, `t1`.`c4`))"
                }
              ] /* steps */
            } /* condition_processing */
          },
          {  ---邏輯優化,條件化簡,結束
            "table_dependencies": [  ---邏輯優化,找出表之間的相互依賴關係,非直接可用的優化方式
              {
                "table": "`t1`",
                "row_may_be_null": false,
                "map_bit": 0,
                "depends_on_map_bits": [
                ] /* depends_on_map_bits */
              }
            ] /* table_dependencies */
          },
          {
            "ref_optimizer_key_uses": [ ---邏輯優化,找出備選的索引
              {
                "table": "`t1`",
                "field": "c2",
                "equals": "'b'",
                "null_rejecting": false
              },
              {
                "table": "`t1`",
                "field": "c4",
                "equals": "20",
                "null_rejecting": false
              },
              {
                "table": "`t1`",
                "field": "c2",
                "equals": "'b'",
                "null_rejecting": false
              },
              {
                "table": "`t1`",
                "field": "c4",
                "equals": "20",
                "null_rejecting": false
              }
            ] /* ref_optimizer_key_uses */
          },
          {
            "rows_estimation": [   --邏輯優化,估算每個表的元組個數,單表上進行全表掃描和索引掃描的代價估算,每個索引都估算掃描代價
              {
                "table": "`t1`",
                "range_analysis": {
                  "table_scan": {    --邏輯優化, 估算每個表的元組個數. 單表上進行全表掃描的代價  
                    "rows": 7,
                    "cost": 4.5
                  } /* table_scan */,
                  "potential_range_indices": [ ---邏輯優化, 列出備選的索引. 後續版本字符串變爲potential_range_ind
                    {
                      "index": "PRIMARY",  ---邏輯優化, 本行表明主鍵索引不可用 
                      "usable": false,     -- 這個表明這個索引不能用於該語句
                      "cause": "not_applicable"
                    },
                    {
                      "index": "ind_c2",  ---邏輯優化, 索引ind_c2  
                      "usable": true,
                      "key_parts": [
                        "c2",
                        "c1"
                      ] /* key_parts */
                    },
                    {
                      "index": "ind_c4", ---邏輯優化, 索引ind_c4
                      "usable": true,
                      "key_parts": [
                        "c4",
                        "c1"
                      ] /* key_parts */
                    },
                    {
                      "index": "ind_c2_c4", ---邏輯優化, 索引ind_c2_c4
                      "usable": true,
                      "key_parts": [
                        "c2",
                        "c4",
                        "c1"
                      ] /* key_parts */
                    }
                  ] /* potential_range_indices */,
                  "setup_range_conditions": [     ---邏輯優化, 如果有可下推的條件,則帶條件考慮範圍查詢  
                  ] /* setup_range_conditions */,
                  "group_index_range": {  ---邏輯優化, 如帶有GROUPBY或DISTINCT,則考慮是否有索引可優化這種操作. 並考慮帶有MIN/MAX的情況  
                    "chosen": false,
                    "cause": "not_group_by_or_distinct"
                  } /* group_index_range */,
                  "analyzing_range_alternatives": {  ---邏輯優化,開始計算每個索引做範圍掃描的花費(等值比較是範圍掃描的特例)  
                    "range_scan_alternatives": [
                      {
                        "index": "ind_c2",
                        "ranges": [
                          "b <= c2 <= b"
                        ] /* ranges */,
                        "index_dives_for_eq_ranges": true,
                        "rowid_ordered": true,
                        "using_mrr": false,
                        "index_only": false,
                        "rows": 4,
                        "cost": 5.81,
                        "chosen": false,
                        "cause": "cost"
                      },
                      {
                        "index": "ind_c4",
                        "ranges": [
                          "20 <= c4 <= 20"
                        ] /* ranges */,
                        "index_dives_for_eq_ranges": true,
                        "rowid_ordered": true,
                        "using_mrr": false,
                        "index_only": false,
                        "rows": 2,
                        "cost": 3.41,      ---邏輯優化,這個索引的代價最小  
                        "chosen": true    ---邏輯優化,這個索引的代價最小,被選中. (比前面的table_scan 和其他索引的代價都小)  
                      },
                      {
                        "index": "ind_c2_c4",
                        "ranges": [
                          "b <= c2 <= b AND 20 <= c4 <= 20"
                        ] /* ranges */,
                        "index_dives_for_eq_ranges": true,
                        "rowid_ordered": true,
                        "using_mrr": false,
                        "index_only": false,
                        "rows": 2,
                        "cost": 3.41,
                        "chosen": false,
                        "cause": "cost"
                      }
                    ] /* range_scan_alternatives */,
                    "analyzing_roworder_intersect": {
                      "intersecting_indices": [
                        {
                          "index": "ind_c2_c4",
                          "index_scan_cost": 1.0476,
                          "cumulated_index_scan_cost": 1.0476,
                          "disk_sweep_cost": 1.75,
                          "cumulated_total_cost": 2.7976,
                          "usable": true,
                          "matching_rows_now": 2,
                          "isect_covering_with_this_index": false,
                          "chosen": true
                        },
                        {
                          "index": "ind_c4",
                          "cumulated_total_cost": 2.7976,
                          "usable": false,
                          "cause": "does_not_reduce_cost_of_intersect"
                        },
                        {
                          "index": "ind_c2",
                          "cumulated_total_cost": 2.7976,
                          "usable": false,
                          "cause": "does_not_reduce_cost_of_intersect"
                        }
                      ] /* intersecting_indices */,
                      "clustered_pk": {
                        "clustered_pk_added_to_intersect": false,
                        "cause": "no_clustered_pk_index"
                      } /* clustered_pk */,
                      "chosen": false,
                      "cause": "too_few_indexes_to_merge"
                    } /* analyzing_roworder_intersect */
                  } /* analyzing_range_alternatives */,  ---邏輯優化,開始計算每個索引做範圍掃描的花費. 這項工作結算  
                  "chosen_range_access_summary": {  ---邏輯優化,開始計算每個索引做範圍掃描的花費. 總結本階段最優的.  
                    "range_access_plan": {
                      "type": "range_scan",
                      "index": "ind_c4",
                      "rows": 2,
                      "ranges": [
                        "20 <= c4 <= 20"
                      ] /* ranges */
                    } /* range_access_plan */,
                    "rows_for_plan": 2,
                    "cost_for_plan": 3.41,
                    "chosen": true    -- 這裏看到的cost和rows都比 indx_user 要來的小很多---這個和[A]處是一樣的,是信息彙總.  
                  } /* chosen_range_access_summary */
                } /* range_analysis */
              }
            ] /* rows_estimation */  ---邏輯優化, 估算每個表的元組個數. 行估算結束
          },
          {
            "considered_execution_plans": [  ---物理優化, 開始多表連接的物理優化計算
              {
                "plan_prefix": [
                ] /* plan_prefix */,
                "table": "`t1`",
                "best_access_path": {
                  "considered_access_paths": [
                    {
                      "access_type": "ref",
                      "index": "ind_c2",
                      "rows": 4,
                      "cost": 2.8,
                      "chosen": true
                    },
                    {
                      "access_type": "ref",  ---物理優化, 計算indx_user索引上使用ref方查找的花費,
                      "index": "ind_c4",
                      "rows": 2,
                      "cost": 2.4,
                      "chosen": true
                    },
                    {
                      "access_type": "ref",
                      "index": "ind_c2_c4",
                      "rows": 2,
                      "cost": 2.4,
                      "chosen": false
                    },
                    {
                      "access_type": "range",  
                      "cause": "heuristic_index_cheaper",
                      "chosen": false
                    }
                  ] /* considered_access_paths */
                } /* best_access_path */,
                "cost_for_plan": 2.4,
                "rows_for_plan": 2,
                "chosen": true
              }
            ] /* considered_execution_plans */
          },
          {
            "attaching_conditions_to_tables": {  --邏輯優化,儘量把條件綁定到對應的表上  
              "original_condition": "((`t1`.`c4` = 20) and (`t1`.`c2` = 'b'))",
              "attached_conditions_computation": [
              ] /* attached_conditions_computation */,
              "attached_conditions_summary": [
                {
                  "table": "`t1`",
                  "attached": "(`t1`.`c2` = 'b')"
                }
              ] /* attached_conditions_summary */
            } /* attaching_conditions_to_tables */
          },
          {
            "refine_plan": [
              {
                "table": "`t1`"  ---邏輯優化,下推索引條件"pushed_index_condition";其他條件附加到表上做爲過濾條件"table_condition_attached"  
              }
            ] /* refine_plan */
          }
        ] /* steps */
      } /* join_optimization */ ---邏輯優化和物理優化結束
    },
    {
      "join_explain": {
        "select#": 1,
        "steps": [
        ] /* steps */
      } /* join_explain */
    }
  ] /* steps */
}
MISSING_BYTES_BEYOND_MAX_MEM_SIZE: 0
          INSUFFICIENT_PRIVILEGES: 0
1 row in set (0.00 sec)


ERROR: 
No query specified


上面是比較各個索引的成本,從輸出上看, ind_c4 的 cost 是 3.41, ind_c2_c4 的cost也是3.41,
     "chosen": true 表明優化器選擇了 ind_c4
    爲什麼會選擇 ind_c4呢?主要是 ind_c2_c4 的掃描範圍更多,
    ranges 是  "b <= c2 <= b AND 20 <= c4 <= 20" ,
    而 ind_c4 是 "20 <= c4 <= 20"







 

發佈了29 篇原創文章 · 獲贊 10 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章