目录
5.1 修改max_length_for_sort_data参数
1. Mysql-执行计划怎么看?
执行计划基础参数解析:
1.id: 查询顺序的编号
2.select_type:表示查询中每个select字句的类型:
3. table:表名
4. partitions:匹配的分区
5. type:判断性能指标
6. possible keys:可能用到索引,也可能用不到
7. key:使用索引名称
8. key_len:使用索引占用字节数
9. ref:列与索引的比较
10. rows:扫描行数
11. filtered:按表条件过滤的行百分比
12. extra:执行情况的描述和说明
2. 强制走索引
格式:select * from 表名 force index(索引名) where 条件 order by 字段名;
EXPLAIN SELECT * FROM mysql.employees force index(idx_name_age_position) WHERE name > 'LiLei' AND age = 22 AND position ='manager';
3. 使用trace工具
1.--关闭查询缓存
set global query_cache_size=0;
set global query_cache_type=0;
2. --开启trace
set session optimizer_trace="enabled=on",end_markers_in_json=on;
3. 使用trace工具分析
格式:
脚本;
SELECT * FROM information_schema.OPTIMIZER_TRACE;
select * from employees where name > 'a' order by position;
SELECT * FROM information_schema.OPTIMIZER_TRACE;
如下图,query是查询得脚本,trace是分析结果,里面提到一个cost得相对值概念,代表了如何选择最优得方案是使用全表扫描还是索引扫描;
4. trace分析结果
里面正常只用关注best_access_path里面得参数,里面分了三部分:
1. join_preparation:SQL准备阶段,格式化sql
2. join_optimization:第二阶段:SQL优化阶段
3. join_execution:第三阶段:SQL执行阶段
{
"steps": [
{
"join_preparation": { ‐‐第一阶段:SQL准备阶段,格式化sql
"select#": 1,
"steps": [
{
"expanded_query": "/* select#1 */ select `employees`.`id` AS `id`,`employees`.`name` AS `name`,`employees`.`age` AS `age`,`employees`.`position` AS `position`,`employees`.`hire_time` AS `hire_time` from `employees` where (`employees`.`name` > 'a') order by `employees`.`position`"
}
] /* steps */
} /* join_preparation */
},
{
"join_optimization": { ‐‐第二阶段:SQL优化阶段
"select#": 1,
"steps": [
{
"condition_processing": { ‐‐条件处理
"condition": "WHERE",
"original_condition": "(`employees`.`name` > 'a')",
"steps": [
{
"transformation": "equality_propagation",
"resulting_condition": "(`employees`.`name` > 'a')"
},
{
"transformation": "constant_propagation",
"resulting_condition": "(`employees`.`name` > 'a')"
},
{
"transformation": "trivial_condition_removal",
"resulting_condition": "(`employees`.`name` > 'a')"
}
] /* steps */
} /* condition_processing */
},
{
"substitute_generated_columns": {
} /* substitute_generated_columns */
},
{
"table_dependencies": [ ‐‐表依赖详情
{
"table": "`employees`",
"row_may_be_null": false,
"map_bit": 0,
"depends_on_map_bits": [
] /* depends_on_map_bits */
}
] /* table_dependencies */
},
{
"ref_optimizer_key_uses": [
] /* ref_optimizer_key_uses */
},
{
"rows_estimation": [ ‐‐预估表的访问成本
{
"table": "`employees`",
"range_analysis": {
"table_scan": { ‐‐全表扫描情况
"rows": 100140, ‐‐扫描行数
"cost": 20383 ‐‐查询成本
} /* table_scan */,
"potential_range_indexes": [ ‐‐查询可能使用的索引
{
"index": "PRIMARY", ‐‐主键索引
"usable": false,
"cause": "not_applicable"
},
{
"index": "idx_name_age_position", ‐‐辅助索引
"usable": true,
"key_parts": [
"name",
"age",
"position",
"id"
] /* key_parts */
}
] /* potential_range_indexes */,
"setup_range_conditions": [
] /* setup_range_conditions */,
"group_index_range": {
"chosen": false,
"cause": "not_group_by_or_distinct"
} /* group_index_range */,
"analyzing_range_alternatives": { ‐‐分析各个索引使用成本
"range_scan_alternatives": [
{
"index": "idx_name_age_position",
"ranges": [
"a < name" ‐‐索引使用范围
] /* ranges */,
"index_dives_for_eq_ranges": true,
"rowid_ordered": false, ‐‐使用该索引获取的记录是否按照主键排序
"using_mrr": false,
"index_only": false, ‐‐是否使用覆盖索引
"rows": 50070, ‐‐索引扫描行数
"cost": 60085, ‐‐索引使用成本
"chosen": false, ‐‐是否选择该索引
"cause": "cost"
}
] /* range_scan_alternatives */,
"analyzing_roworder_intersect": {
"usable": false,
"cause": "too_few_roworder_scans"
} /* analyzing_roworder_intersect */
} /* analyzing_range_alternatives */
} /* range_analysis */
}
] /* rows_estimation */
},
{
"considered_execution_plans": [
{
"plan_prefix": [
] /* plan_prefix */,
"table": "`employees`",
"best_access_path": { ‐‐最优访问路径
"considered_access_paths": [ ‐‐最终选择的访问路径
{
"rows_to_scan": 100140,
"access_type": "scan", ‐‐访问类型:为scan,全表扫描
"resulting_rows": 100140,
"cost": 20381,
"chosen": true, ‐‐确定选择
"use_tmp_table": true
}
] /* considered_access_paths */
} /* best_access_path */,
"condition_filtering_pct": 100,
"rows_for_plan": 100140,
"cost_for_plan": 20381,
"sort_cost": 100140,
"new_cost_for_plan": 120521,
"chosen": true
}
] /* considered_execution_plans */
},
{
"attaching_conditions_to_tables": {
"original_condition": "(`employees`.`name` > 'a')",
"attached_conditions_computation": [
] /* attached_conditions_computation */,
"attached_conditions_summary": [
{
"table": "`employees`",
"attached": "(`employees`.`name` > 'a')"
}
] /* attached_conditions_summary */
} /* attaching_conditions_to_tables */
},
{
"clause_processing": {
"clause": "ORDER BY",
"original_clause": "`employees`.`position`",
"items": [
{
"item": "`employees`.`position`"
}
] /* items */,
"resulting_clause_is_simple": true,
"resulting_clause": "`employees`.`position`"
} /* clause_processing */
},
{
"reconsidering_access_paths_for_index_ordering": {
"clause": "ORDER BY",
"index_order_summary": {
"table": "`employees`",
"index_provides_order": false,
"order_direction": "undefined",
"index": "unknown",
"plan_changed": false
} /* index_order_summary */
} /* reconsidering_access_paths_for_index_ordering */
},
{
"refine_plan": [
{
"table": "`employees`"
}
] /* refine_plan */
}
] /* steps */
} /* join_optimization */
},
{
"join_execution": { ‐‐第三阶段:SQL执行阶段
"select#": 1,
"steps": [
{
"filesort_information": [
{
"direction": "asc",
"table": "`employees`",
"field": "position"
}
] /* filesort_information */,
"filesort_priority_queue_optimization": {
"usable": false,
"cause": "not applicable (no LIMIT)"
} /* filesort_priority_queue_optimization */,
"filesort_execution": [
] /* filesort_execution */,
"filesort_summary": {
"rows": 100003,
"examined_rows": 100003,
"number_of_tmp_files": 30,
"sort_buffer_size": 262056,
"sort_mode": "<sort_key, packed_additional_fields>"
} /* filesort_summary */
}
] /* steps */
} /* join_execution */
}
] /* steps */
}
5. 关闭trace
set session optimizer_trace="enabled=off";
6. 缓存命令
--查询是否开启缓存
show variables like '%query_cache%';
--开启查询缓存
set global query_cache_size=500M;
set global query_cache_type=ON;
4. 索引下推概念
mysql5.6之前,匹配like+关键字得索引,查询以后用主键回表查询,再对比后面得查询条件;
mysql5.6之后,匹配like+关键字得索引,会加上后面得其他字段查询条件,过滤掉一些不需要得数据以后再用主键ID做回表。
5. 使用文件排序排序原理
mysql支持两种排序,一种filesort,一种index,可以在extra参数里面看到,文件排序又分为单路和双路排序,以下是摘抄内容:
5.1 修改max_length_for_sort_data参数
set max_length_for_sort_data = 10;