Mysql学习笔记

慢查询

1 慢查询优化思路

当发生慢查询的时候,优化的思路为:

  • 利用慢查询日志定位慢查询 SQL
  • 通过 explain 分析慢查询 SQL
  • 修改 SQL,尽量让 SQL 走索引
2 慢查询日志

MySQL 提供了一个功能——慢查询日志,会记录查询时间超过指定时间阈值的 SQL 到日志中,便于我们定位慢查询并且优化对应的 SQL 语句。

首先查看 MySQL 中关于慢查询相关的全局变量:

mysql> show global variables like '%quer%';
+----------------------------------------+-------------------------------+
| Variable_name                          | Value                         |
+----------------------------------------+-------------------------------+
| binlog_rows_query_log_events           | OFF                           |
| ft_query_expansion_limit               | 20                            |
| have_query_cache                       | YES                           |
| log_queries_not_using_indexes          | OFF                           |
| log_throttle_queries_not_using_indexes | 0                             |
==========================================================================
| long_query_time                        | 10.000000                     |【1】慢查询的时间阈值
==========================================================================
| query_alloc_block_size                 | 8192                          |
| query_cache_limit                      | 1048576                       |
| query_cache_min_res_unit               | 4096                          |
| query_cache_size                       | 16777216                      |
| query_cache_type                       | OFF                           |
| query_cache_wlock_invalidate           | OFF                           |
| query_prealloc_size                    | 8192                          |
==========================================================================
| slow_query_log                         | OFF                           |【2】慢查询日志是否开启
| slow_query_log_file                    | /var/lib/mysql/Linux-slow.log |【3】慢查询日志文件存储位置
==========================================================================
+----------------------------------------+-------------------------------+
15 rows in set (0.00 sec)

这里主要关注三个变量:

  • long_query_time,慢查询的时间阈值,单位秒,如果一个 SQL 语句的执行时间超过这个值,那么 MySQL 就认定其为慢查询
  • slow_query_log,慢查询日志功能是否开启,默认关闭,开启后记录慢查询
  • slow_query_log_file,慢查询日志文件的存储位置

默认慢查询日志功能是关闭的,因此我们需要启动该功能

# 开启慢查询日志
mysql> set global slow_query_log=ON;
Query OK, 0 rows affected (0.00 sec)
# 设置慢查询时间阈值
mysql> set long_query_time=1;
Query OK, 0 rows affected (0.00 sec)

这样子设置后,MySQL 重启会丢失这些配置,需要在配置文件中修改才会永久有效。

3 explain

我们可以使用 explain 分析 SQL 语句的执行情况,例如:

mysql> explain select sum(1+2);

执行结果如下,可以看到有很多字段

  • select_type 表示查询语句的查询类型,包括简单查询、子查询等等
  • table 表示查询的表,不一定是存在表,可能是本次查询中得到的临时表
  • type 表示检索类型,使用全表扫描、还是索引扫描等
  • possible_keys表示可能使用的索引列
  • keys表示查询中实际使用的索引列,由查询优化器决定

大表加字段的方案

MySQL的大表增加字段是一个比较经常遇到的问题,当我们需要在已经存在的大表中添加一个或多个字段时,这个过程可能会非常耗时,数据量越大,所需的时间也会越长。在这里,我们提供几种方案来提高这个过程的效率:

1.使用ALTER TABLE语句添加字段
ALTER TABLE table_name ADD COLUMN column_name data_type;

这是最常用的方式,但是在大表中添加字段可能需要一定的时间。特别是在一个非常大的表中添加新列时,可能会需要一些时间来进行这个过程。另外,这种方式还需要考虑锁表,容易造成生产环境的中断,因此需要谨慎操作。

2.使用pt-online-schema-change工具
pt-online-schema-change --alter "ADD COLUMN column_name data_type" D=database,t=table_name

pt-online-schema-change是一个由Percona公司开发的工具,它基于 MySQL 实现了一个在线 DDL 工具。pt-online-schema-change的主要作用是在MySQL不停机的前提下,修改表结构。通常情况下,这种方式在处理大表时方案一更加有效。

3.使用MyDumper工具导出表数据,新建表空间添加字段,再导入数据到新表
#导出数据
mydumper -h hostname -u username -p password -B dbname -q 1 -o /path/to/dumpdir
#新建表空间和添加字段
CREATE TABLE new_table (column1 type1, ..., columnN typeN, new_column_1 ..., new_column_N);
#导入数据到新表
myloader -h hostname -u username -p password -B dbname -d /path/to/dumpdir

这种方式适用于添加多个字段,或是涉及到表结构的大规模修改。将大表数据导出,新建一张表空间,并添加新的字段,然后将数据导入到新表空间中。该方案的优点是可以在导入数据的同时,进行表结构的调整。但是,在处理大规模的修改时,需要注意数据同步的问题。

数据存在则更新,不存在则插入

1.存在则更新(不影响其他字段),不存在则插入
insert into 表名(字段1,字段2) VALUES(值1,值2) ON DUPLICATE KEY UPDATE username=值3

如上语句的意思的意思是如果字段1不存在(主键,索引或者唯一条件不存在),则执行插入语句,存在则执行更新语句,该更新只更新需要的字段,不影响其他字段的值;

2.存在则更新(先删除后更新),不存在则插入
REPLACE INTO 表名(字段1,字段2) VALUES(值A,值B);

如上语句的意思的意思是如果字段1不存在(主键,索引或者唯一条件不存在),则执行插入语句,存在则执行更新语句,该更新是将该条存在的记录删除,然后再插入,所以其他的字段的值都是NULL;

3.存在则忽略,不存在插入
INSERT IGNORE INTO 表名(字段1,字段2) VALUES(值A,值B);

如上语句的意思是如果字段1不存在(主键,索引或者唯一条件不存在),则执行插入语句,如果存在,直接忽略不修改任何数据

  • 28
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值