慢查询排查以及优化

排查方式

SHOW PROCESSLIST

SHOW PROCESSLIST 只能查看到当前用户正在运行的线程,如果你是ROOT用户,那么是可以看到所有用户正在运行的线程
如果想看到其他用户的线程,则必须为此用户赋予 PROCESS 权限。

危害:

  1. 造成机器的 CPU 以及 IO 过高,影响到数据库实例。
  2. 阻塞 DDL 查询语句,会造成其他正常业务出现耗时过高。
  3. 会导致 mysql 出现 MDL 锁,影响到该机器上正常 SQL 的执行。
阅读更多

mysql中count(*)和count(1)的区别

在进行旧的项目 review 的时候,我发现绝大多数的统计SQL都是基于 count(1) 来进行的,只有一少部分是基于 count(*),那么这两种写法到底有什么区别。

mysql中,常用的存储引擎有myisaminnodb,但是由于myisam只支持表级别锁,而且还不支持事物,所以在mysql的5.5版本之后就将默认的存储引擎调整为innodb

 
以下实验基于 Mysql8.0.1 来进行
 

首先这里准备了一个表.

阅读更多

MySql中int类型的简单总结

问题

首先问两个问题:

  1. int(1)和int(10)有什么区别。
  2. int(3)可以存储 10000 这个数字吗?
  3. int(11)可以用来存储手机号么?

本次的源代码以及测试的 Mysql 版本均为 8.0.17

解释

阅读更多

MySql的幻读(二)

定义

在InnoDB里面,是通过快照读来实现RCPR隔离级别的区分,因为在RC隔离级别下,每一次的select都是一个快照读,所以是可以读取到已经提交的数据,从而导致幻读。所以在RC隔离级别下,快照读和当前读都是可以出现幻读。

但是在PR的隔离级别下,由于快照读仅仅只生成一次,所以在PR级别下的快照读是无法出现幻读的,但是当前读确实可以出现幻读。

查看Mysql官方对于幻读的定义。

The so-called phantom problem occurs within a transaction when the same query produces different sets of rows at different times.

阅读更多

MySql中的幻读(一)

什么是幻读

幻读表示的是在一个事物里面 同一个select语句,前后两次查询出来的结果是不相同的,需要注意的一点是,在InnoDB里面,幻读跟事物的隔离级别有关,更加准确的说是跟一个事物的快照和当前读有关

下面是在Mysql8.0.11版本下进行幻读的复现:

  • 引擎:InnoDB
  • 事物隔离级别:Read Commited

MVCC和快照读以及当前读

阅读更多

MySql数据库出现死锁的情况(一)

在临近上线之前,我们系统做了一次压力测试,发现有一个接口在高并发情况下会出现一个死锁的情况。。首先申明…不是我写的,我只是帮忙排查下。

随着对Mysql锁的深入了解,于是就准备写几篇文章来记录下Mysql各种事物和索引的情况下出现死锁的情况。

今天就介绍下在并发插入的情况下,哪几种情况会出现死锁:

INNODB下的各种锁

在介绍锁的时候只会介绍跟本节相关的锁,而且只会讲述大概是什么,至于锁的更加详细的讲解可能会到以后再详细介绍。

阅读更多

数据库调优(一)

开篇

在上一篇文章中,我们有一个表,里面的内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
mysql> select * from org_copy;
+--------+-----------------+---------------+----------+
| org_id | org_name | org_parent_id | org_copy |
+--------+-----------------+---------------+----------+
| 1 | 一级部门 | 0 | 1 |
| 2 | 一一级部门 | 0 | 2 |
| 3 | 1.1级部门 | 1 | 3 |
| 4 | 1.2级部门 | 1 | 4 |
| 5 | 1.1.1部门 | 3 | 5 |
| 6 | 1.1.2部门 | 3 | 6 |
| 7 | 1.1.1.1部门 | 5 | 7 |
| 8 | 1.3部门 | 1 | 8 |
| 9 | 1.2.1部门 | 4 | 9 |
+--------+-----------------+---------------+----------+
9 rows in set (0.00 sec)

这应该是一个很基本的一个mysql表,同时我们在上一篇文章中,也执行了如下SQL。

1
2
3
4
5
6
7
8
mysql> explain SELECT * FROM org_copy WHERE org_name>'一级部门' and  org_parent_id=1;
+----+-------------+----------+------------+-------+---------------+------------+---------+------+------+----------+-----------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+----------+------------+-------+---------------+------------+---------+------+------+----------+-----------------------+
| 1 | SIMPLE | org_copy | NULL | range | index_name | index_name | 768 | NULL | 1 | 11.11 | Using index condition |
+----+-------------+----------+------------+-------+---------------+------------+---------+------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)

阅读更多

数据库最左原则以及理解

本次的实验是基于Mysql8版本。首先在数据库中有一个表,其结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> show create table org;
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| org | CREATE TABLE `org` (
`org_id` int(5) NOT NULL,
`org_name` varchar(255) DEFAULT NULL,
`org_parent_id` int(5) DEFAULT NULL,
PRIMARY KEY (`org_id`),
KEY `index_name` (`org_name`,`org_parent_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

可以看到在这个表中,有一个主键org_id以及一个联合索引index_name。其他的并无特别之处。

最左原则

在Mysql里面,有一个最左原则,官网的介绍如下:

阅读更多

在Mysql中使用变量进行复杂的查询(一)

注意,此文章使用的Mysql变量均是用户变量

简介

首先看一个需求,有如下数据表:

1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> select * from t1 order by area_id;
+---------+-----------+
| area_id | order_num |
+---------+-----------+
| 1 | 22 |
| 1 | 10 |
| 1 | 10 |
| 2 | 10 |
| 2 | 10 |
| 2 | 22 |
| 3 | 10 |
+---------+-----------+
7 rows in set (0.14 sec)

可以看到,这是一个很非常普通的数据表。

阅读更多

MySql之binlog的使用(一)

背景

假设有一个如下的业务场景如下:
需要记录一个商品或者股票的实时价格,每一个小时记录一次,而商品或者股票的数量十分多,这时业务发展到一定的程度之后就需要考虑数据库的设计。首先商品每个小时的价格肯定是需要入库的。其次每小时的购买人群以及各种埋点数据随之一起也要入库。以便于日后的数据分析。

解决方案

随着数据量的增大,一般的解决方案是设置索引,然后再考虑是进行垂直还是水平分库分表。

但是一旦使用水平分库分表就会无形之间增加开发的复杂程度,而且分库分表之后考虑的各种因素也会随之而来增加数倍。例如各种表的唯一ID以及如何进行维度的划分。

阅读更多