0
点赞
收藏
分享

微信扫一扫

MYSQL SQL优化思路和方法

皮皮球场 2024-05-13 阅读 14

MYSQL SQL优化思路和方法

一、优化SQL的一般步骤

1.1 了解各种SQL执行频率

mysql> show status like '%Com_%';
+-----------------------------+-------+
| Variable_name               | Value |
+-----------------------------+-------+
| 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               | 0     |
| 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              | 0     |
| 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   |
| Flush_commands              | 1     |
| Handler_commit              | 0     |
+-----------------------------+-------+
151 rows in set (0.00 sec)

针对的是所有存储引擎的表:
Com_select:执行select操作的次数,1次查询累计加1;
Com_insert:执行insert操作的次数,批量insert操作,只累加1;
Com_update:执行update操作的次数;
Com_delete:执行delete操作的次数。

针对Innodb存储引擎的表:
innodb_rows_read:select查询返回的行数;
innodb_row_inserted:执行insert操作插入的行数;
innodb_rows_updated:执行update操作更新的行数;
innodb_rows_deleted:执行deleted操作删除的行数。

针对事务型的应用:
Com_commit:事务提交的次数
Com_rollback:事务回滚的次数

了解数据库基本情况
Connections:视图连接Mysql服务器的次数;
Uptime:服务器工作时间;
Slow_queries:慢查询的次数。

1.2 定位执行效率较低SQL

1.3 Explain分析低效SQL执行计划

mysql> EXPLAIN
   -> SELECT
   ->     c.name AS CustomerName,
   ->     COUNT(o.id) AS NumberOfOrders,
   ->     SUM(o.amount) AS TotalSpent,
   ->     MAX(o.order_date) AS LastOrderDate
   -> FROM
   ->     customers c
   -> JOIN
   ->     orders o ON c.id = o.customer_id
   -> WHERE
   ->     o.order_date >= DATE_SUB(CURDATE(), INTERVAL 1 YEAR)
   -> GROUP BY
   ->     c.id, c.name
   -> HAVING
   ->     SUM(o.amount) > 1000
   -> ORDER BY
   ->     TotalSpent DESC;
+----+-------------+-------+------------+--------+---------------+---------+---------+----------------------+-------+----------+----------------------------------------------+
| id | select_type | table | partitions | type   | possible_keys | key     | key_len | ref                  | rows  | filtered | Extra                                        |
+----+-------------+-------+------------+--------+---------------+---------+---------+----------------------+-------+----------+----------------------------------------------+
|  1 | SIMPLE      | o     | NULL       | ALL    | customer_id   | NULL    | NULL    | NULL                 | 10294 |    33.33 | Using where; Using temporary; Using filesort |
|  1 | SIMPLE      | c     | NULL       | eq_ref | PRIMARY       | PRIMARY | 4       | sbtest.o.customer_id |     1 |   100.00 | NULL                                         |
+----+-------------+-------+------------+--------+---------------+---------+---------+----------------------+-------+----------+----------------------------------------------+
2 rows in set, 1 warning (0.00 sec)

table:输出结果集的表
type:表的连接类型,性能由好到差的连接类型为:

possible_keys:表示查询时,可能使用的索引
key:表示实际使用的索引
key_len:索引字段的长度
rows:扫描行的数量
extra:执行情况的说明和描述

1.4 确定问题并采取相应的优化措施

二、索引问题

2.1 索引的存储分类

2.2 如何使用索引

2.2.1 使用索引

mysql> create index idx_t1 on orders(order_date,amount);

mysql> show index from orders;
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table  | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| orders |          0 | PRIMARY  |            1 | id          | A         |       10294 |     NULL | NULL   |      | BTREE      |         |               |
| orders |          1 | idx_cid  |            1 | customer_id | A         |        6305 |     NULL | NULL   |      | BTREE      |         |               |
| orders |          1 | idx_t1   |            1 | order_date  | A         |         730 |     NULL | NULL   |      | BTREE      |         |               |
| orders |          1 | idx_t1   |            2 | amount      | A         |       10003 |     NULL | NULL   |      | BTREE      |         |               |
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
4 rows in set (0.00 sec)

mysql> explain select * from orders where order_date = '2024-5-10';
+----+-------------+--------+------------+------+---------------+--------+---------+-------+------+----------+-------+
| id | select_type | table  | partitions | type | possible_keys | key    | key_len | ref   | rows | filtered | Extra |
+----+-------------+--------+------------+------+---------------+--------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | orders | NULL       | ref  | idx_t1        | idx_t1 | 3       | const |   13 |   100.00 | NULL  |
+----+-------------+--------+------------+------+---------------+--------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)


mysql> explain select * from orders where amount = 1851.69;
+----+-------------+--------+------------+------+---------------+------+---------+------+-------+----------+-------------+
| id | select_type | table  | partitions | type | possible_keys | key  | key_len | ref  | rows  | filtered | Extra       |
+----+-------------+--------+------------+------+---------------+------+---------+------+-------+----------+-------------+
|  1 | SIMPLE      | orders | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 10294 |    10.00 | Using where |
+----+-------------+--------+------------+------+---------------+------+---------+------+-------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
mysql> create index idx_name on customers(name);

mysql> explain select * from customers where name like '%1';
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table     | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | customers | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 9809 |    11.11 | Using where |
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

mysql> explain select * from customers where name like 'Customer_101%';
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table     | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | customers | NULL       | ALL  | idx_name      | NULL | NULL    | NULL | 9809 |    49.99 | Using where |
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

2.2.2 存在索引但不使用索引

2.2.3 查看索引使用情况

mysql>  show status like 'handler_read%';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| Handler_read_first    | 4     |
| Handler_read_key      | 4     |
| Handler_read_last     | 0     |
| Handler_read_next     | 10003 |
| Handler_read_prev     | 0     |
| Handler_read_rnd      | 0     |
| Handler_read_rnd_next | 10030 |
+-----------------------+-------+

2.3 简单实用的优化方法

2.3.1 定期分析表和检查表

analyze [local | no_write_to_binlog] table table_name1 [, table_name2]...

mysql> analyze table orders;
+---------------+---------+----------+----------+
| Table         | Op      | Msg_type | Msg_text |
+---------------+---------+----------+----------+
| sbtest.orders | analyze | status   | OK       |
+---------------+---------+----------+----------+
1 row in set (0.01 sec)

mysql> analyze no_write_to_binlog table orders;
+---------------+---------+----------+----------+
| Table         | Op      | Msg_type | Msg_text |
+---------------+---------+----------+----------+
| sbtest.orders | analyze | status   | OK       |
+---------------+---------+----------+----------+
1 row in set (0.02 sec)

·· 检查一个表有没有问题
mysql> check table orders;
+---------------+-------+----------+----------+
| Table         | Op    | Msg_type | Msg_text |
+---------------+-------+----------+----------+
| sbtest.orders | check | status   | OK       |
+---------------+-------+----------+----------+
1 row in set (0.03 sec)

2.3.2 定期优化表

mysql> optimize table orders;
+---------------+----------+----------+-------------------------------------------------------------------+
| Table         | Op       | Msg_type | Msg_text                                                          |
+---------------+----------+----------+-------------------------------------------------------------------+
| sbtest.orders | optimize | note     | Table does not support optimize, doing recreate + analyze instead |
| sbtest.orders | optimize | status   | OK                                                                |
+---------------+----------+----------+-------------------------------------------------------------------+
2 rows in set (0.41 sec)

2.4 常用SQL优化

2.4.1 大批量插入数据

alter table table_name disable keys;
loading the data...
alter table table_name enable keys;

2.4.2 优化INSERT语句

2.4.3 优化GROUP BY语句

mysql> explain select address  from customers group by address;
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+---------------------------------+
| id | select_type | table     | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra                           |
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+---------------------------------+
|  1 | SIMPLE      | customers | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 9809 |   100.00 | Using temporary; Using filesort |
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+---------------------------------+
1 row in set, 1 warning (0.00 sec)

mysql> explain select address  from customers group by address order by null;
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-----------------+
| id | select_type | table     | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra           |
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-----------------+
|  1 | SIMPLE      | customers | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 9809 |   100.00 | Using temporary |
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-----------------+
1 row in set, 1 warning (0.00 sec)

2.4.4 优化ORDER BY语句

2.4.5 优化嵌套查询

2.4.6 优化OR条件

2.4.6 使用SQL提示

SELECT SQL_BUFFER_RESULTS * FROM...

三、小结

举报

相关推荐

0 条评论