优化MySQL语句的一般步骤
- 通过show status命令了解各种sql的执行频率
mysql show status like 'Com_%'
Com_admin_commands 0
Com_assign_to_keycache 0
Com_alter_db 0
Com_alter_db_upgrade 0
Com_alter_event 0
Com_alter_function 0
Com_alter_instance 0
Com_alter_procedure 0
Com_alter_server 0
Com_alter_table 0
Com_alter_tablespace 0
Com_alter_user 0
Com_analyze 0
Com_begin 0
Com_binlog 0
Com_call_procedure 0
Com_change_db 1
Com_change_master 0
Com_change_repl_filter 0
Com_check 0
Com_checksum 0
Com_commit 0
Com_create_db 0
Com_create_event 0
Com_create_function 0
Com_create_index 0
Com_create_procedure 0
Com_create_server 0
Com_create_table 0
Com_create_trigger 0
Com_create_udf 0
Com_create_user 0
Com_create_view 0
Com_dealloc_sql 0
Com_delete 0
Com_delete_multi 0
Com_do 0
Com_drop_db 0
Com_drop_event 0
Com_drop_function 0
Com_drop_index 0
Com_drop_procedure 0
Com_drop_server 0
Com_drop_table 0
Com_drop_trigger 0
Com_drop_user 0
Com_drop_view 0
Com_empty_query 0
Com_execute_sql 0
Com_explain_other 0
Com_flush 0
Com_get_diagnostics 0
Com_grant 0
Com_ha_close 0
Com_ha_open 0
Com_ha_read 0
Com_help 0
Com_insert 0
Com_insert_select 0
Com_install_plugin 0
Com_kill 0
Com_load 0
Com_lock_tables 0
Com_optimize 0
Com_preload_keys 0
Com_prepare_sql 0
Com_purge 0
Com_purge_before_date 0
Com_release_savepoint 0
Com_rename_table 0
Com_rename_user 0
Com_repair 0
Com_replace 0
Com_replace_select 0
Com_reset 0
Com_resignal 0
Com_revoke 0
Com_revoke_all 0
Com_rollback 0
Com_rollback_to_savepoint 0
Com_savepoint 0
Com_select 0
Com_set_option 2
Com_signal 0
Com_show_binlog_events 0
Com_show_binlogs 0
Com_show_charsets 0
Com_show_collations 0
Com_show_create_db 0
Com_show_create_event 0
Com_show_create_func 0
Com_show_create_proc 0
Com_show_create_table 0
Com_show_create_trigger 0
Com_show_databases 0
Com_show_engine_logs 0
Com_show_engine_mutex 0
Com_show_engine_status 0
Com_show_events 0
Com_show_errors 0
Com_show_fields 0
Com_show_function_code 0
Com_show_function_status 0
Com_show_grants 0
Com_show_keys 0
Com_show_master_status 0
Com_show_open_tables 0
Com_show_plugins 0
Com_show_privileges 0
Com_show_procedure_code 0
Com_show_procedure_status 0
Com_show_processlist 0
Com_show_profile 0
Com_show_profiles 0
Com_show_relaylog_events 0
Com_show_slave_hosts 0
Com_show_slave_status 0
Com_show_status 3
Com_show_storage_engines 0
Com_show_table_status 0
Com_show_tables 0
Com_show_triggers 0
Com_show_variables 0
Com_show_warnings 0
Com_show_create_user 0
Com_shutdown 0
Com_slave_start 0
Com_slave_stop 0
Com_group_replication_start 0
Com_group_replication_stop 0
Com_stmt_execute 0
Com_stmt_close 0
Com_stmt_fetch 0
Com_stmt_prepare 0
Com_stmt_reset 0
Com_stmt_send_long_data 0
Com_truncate 0
Com_uninstall_plugin 0
Com_unlock_tables 0
Com_update 0
Com_update_multi 0
Com_xa_commit 0
Com_xa_end 0
Com_xa_prepare 0
Com_xa_recover 0
Com_xa_rollback 0
Com_xa_start 0
Com_stmt_reprepare 0
Compression OFF
Com_xxx表示每个xxx语句执行的次数, 通常比较关心一下几个统计参数。
Com_select: 执行select操作的次数,一次查询只累加1.
Com_insert: 执行insert操作的次数,对于批量插入的insert操作,只累加一次
Com_update: 执行update操作的次数。
Com_delete: 执行delete操作的次数。
以上这些参数对所有的存储引擎的表都会进行累计。
下面的参数只针对InoDB存储引擎,累加算法也略有不同。
Innodb_rows_read: select查询返回的行数
Innodb_rows_inserted: 执行insert操作插入的行数
Innodb_rows_updated: 执行update操作更新的行数
Innodb_rows_deleted: 执行delete操作删除的行数
** 对于事务性应用,通过Com_commit和Com_rollback可以了解事务的提交和回滚情况。**
这几个参数是用于了解数据库的基本情况。
Connections: 试图了解Mysql服务器的次数
Uptime: 服务器工作时间
Slow_queies: 慢查询次数。
- 定位执行效率较低的sql语句
- 通过慢查询日志定位执行效率较低的SQL语句,用--log-slow-queries[=file_name]选项启动,
- 使用show processlist命令查看当前mysql进行的进程,实时查看SQL执行情况。
- 通过explain分析低效的SQL执行计划
mysql> explain select * from runoob\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: runoob
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 3
filtered: 100.00
Extra: NULL
1 row in set, 1 warning (0.01 sec)
对每个列简单说明下
* select_type: 表示select类型,常见值有simple(简单表,不使用表连接或子查询)、primary(主查询,即外层的查询)、union(union中的第二个或后面的查询语句)、subquery(子查询的第一个select等)
* table: 表示结果集表
* type: 表示mysql在表的找到所需行的方式,或者访问类型。常见如下
| ALL | index | range | ref | eq_ref | const,system | NULL |
从左到右,性能由最差到最好。
1、type=ALL,全表扫描, MySQL遍历全表来找到匹配的行:
2、type=index, 索引全扫描, MySQL遍历整个索引来查询匹配的行
3、type=range,索引范围扫描, 常见于<、<= 、> 、>= 、between等操作符
4、type=ref, 使用非唯一索引扫描或唯一索引扫描的前缀扫描,返回匹配某个单独值得记录行
5、type=eq_ref,类似ref,区别在于使用索引是唯一索引,对于每个索引键值表中只有一条记录行,简单说就是夺标连接中使用porimary key 或者unique index 作为关联条件
6、type=const,system,单表中最多有一个匹配行,查询起来非常迅速,所以这个匹配行中其他列的值可以被优化器在当前查询中当常量来处理。
7、type=NULL,MySQL不用访问表或者索引,直接能够得到结果
mysql> explain select 1 from dual where 1\G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: NULL
partitions: NULL
type: NULL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: NULL
filtered: NULL
Extra: No tables used
1 row in set, 1 warning (0.00 sec)
ERROR:
No query specified
通过show profile分析SQL
- 通过have_profiling参数,查看MySQL是否支持profile
mysql> select @@have_profiling;
+------------------+
| @@have_profiling |
+------------------+
| YES |
+------------------+
1 row in set, 1 warning (0.00 sec)
默认profiling是关闭的,可以通过set语句在Session级别开启profiling:
mysql> set profiling=1
Query OK, 0 rows affected(0.00 sec)
- 通过show profile for query 语句能看到执行过程中线程的每个状态和消耗时间
通过trace分析优化器如何选择执行计划
- MySQL5.6提供了SQL跟踪的trace,通过trace文件能够进一步了解优化器的行为。
- 使用方式: 首先打开trace, 设置格式为JSON, 设置trace最大能够使用的内存大小,避免解析过程因默认内存太小而不能完整显示。
mysql>set optimizer_trace='enabled=on',end_markers_in_json=on;
Query OK, 0 rows affected(0.03 sec)
mysql>set optimizer_trace_max_mem_size = 10000000;
Query OK, 0 rows affected(0.00 sec)
- 最后检查infomation_schema.optimizer_trace就可以知道MySQL是如何执行SQL的。
mysql>select * from infomation_schema.optimizer_trace\G;
网友评论