SQL优化
- MySQL优化
- SQL优化-不要写select *
- SQL优化-小表驱动大表,而不是大表驱动小表
- SQL优化-连接查询代替子查询
- SQL优化-提升group by的效率
- SQL优化-使用limit
- SQL优化-union all代替union
- SQL优化-join的表不宜过多
MySQL优化
- trace工具
set session optimizer_trace='enabled=on',end_markers_in_json =on; -- 开启trace
select * From employees where name ='ddd';
select * from information_schema.OPTIMIZER_TRACE;
- trace
{"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`,`employees`.`remark` AS `remark`,`employees`.`salary` AS `salary` from `employees` where (`employees`.`name` = 'ddd')"}] /* steps */} /* join_preparation */},{"join_optimization": { -- 第二阶段,SQL优化阶段"select#": 1,"steps": [{"condition_processing": { -- 条件处理"condition": "WHERE","original_condition": "(`employees`.`name` = 'ddd')","steps": [{"transformation": "equality_propagation","resulting_condition": "multiple equal('ddd', `employees`.`name`)"},{"transformation": "constant_propagation","resulting_condition": "multiple equal('ddd', `employees`.`name`)"},{"transformation": "trivial_condition_removal","resulting_condition": "multiple equal('ddd', `employees`.`name`)"}] /* 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": [{"table": "`employees`","field": "name","equals": "'ddd'","null_rejecting": true}] /* ref_optimizer_key_uses */},{"rows_estimation": [ -- 预估表的访问成本{"table": "`employees`","range_analysis": {"table_scan": { --全表扫描情况"rows": 10, -- 扫描行数,"cost": 3.35 -- 查询成本} /* 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 */,"skip_scan_range": {"potential_skip_scan_indexes": [{"index": "idx_name_age_position","usable": false,"cause": "query_references_nonkey_column"}] /* potential_skip_scan_indexes */} /* skip_scan_range */,"analyzing_range_alternatives": {"range_scan_alternatives": [{"index": "idx_name_age_position","ranges": ["name = 'ddd'" -- 索引使用范围] /* ranges */,"index_dives_for_eq_ranges": true,"rowid_ordered": false,"using_mrr": false,"index_only": false,"in_memory": 1,"rows": 1, -- 索引扫描行数"cost": 0.61, -- 索引使用成本"chosen": true -- 是否使用该索引}] /* range_scan_alternatives */,"analyzing_roworder_intersect": {"usable": false,"cause": "too_few_roworder_scans"} /* analyzing_roworder_intersect */} /* analyzing_range_alternatives */,"chosen_range_access_summary": {"range_access_plan": {"type": "range_scan","index": "idx_name_age_position","rows": 1,"ranges": ["name = 'ddd'"] /* ranges */} /* range_access_plan */,"rows_for_plan": 1,"cost_for_plan": 0.61,"chosen": true} /* chosen_range_access_summary */} /* range_analysis */}] /* rows_estimation */},{"considered_execution_plans": [{"plan_prefix": [] /* plan_prefix */,"table": "`employees`","best_access_path": {"considered_access_paths": [{"access_type": "ref", -- 访问类型:ref,使用索引,如果是scan,则为全表扫描"index": "idx_name_age_position","rows": 1,"cost": 0.35,"chosen": true --确定选择},{"access_type": "range","range_details": {"used_index": "idx_name_age_position"} /* range_details */,"chosen": false,"cause": "heuristic_index_cheaper"}] /* considered_access_paths */} /* best_access_path */,"condition_filtering_pct": 100,"rows_for_plan": 1,"cost_for_plan": 0.35,"chosen": true}] /* considered_execution_plans */},{"attaching_conditions_to_tables": {"original_condition": "(`employees`.`name` = 'ddd')","attached_conditions_computation": [] /* attached_conditions_computation */,"attached_conditions_summary": [{"table": "`employees`","attached": "(`employees`.`name` = 'ddd')"}] /* attached_conditions_summary */} /* attaching_conditions_to_tables */},{"finalizing_table_conditions": [{"table": "`employees`","original_table_condition": "(`employees`.`name` = 'ddd')","final_table_condition ": null}] /* finalizing_table_conditions */},{"refine_plan": [{"table": "`employees`"}] /* refine_plan */}] /* steps */} /* join_optimization */},{"join_execution": { --第三阶段:SQL执行阶段"select#": 1,"steps": [] /* steps */} /* join_execution */}] /* steps */
}
SQL优化-不要写select *
SQL优化-小表驱动大表,而不是大表驱动小表
SQL优化-连接查询代替子查询
SQL优化-提升group by的效率
给group by后面的字段添加索引