[[TOC]]

常用操作指令

  • show databases:显示所有的数据库;
  • use dbName: 使用指定数据库
  • show tables: 显示所有的数据表;
  • desc tableName: 查看数据表的字段信息;
  • show create table tableName: 查询创建表的所有信息;
  • show create database dbName: 查看数据库创建指令;
  • show full processlist: 查看所有进程
  • drop table tableName: 删除表
  • alter table tableName add constraint 主键(如:PK_TableName) primary key tableName(主键字段):添加主键约束
  • alter table tableName add constraint 从表 (如:FK_从表_主表) foreign key 从表(外键字段) references 主表(主键字段): 添加外键约束
  • alter table tableName add constraint 唯一约束 (如:uk_t_1) unique(字段名): 添加唯一约束;
  • alter table tableName drop primary key: 删除主键约束
  • alter table tableName drop foreign key 外键(区分大小写): 删除外键约束
  • alter table tableName add index value_domain_idx(domain_id, value): 添加索引value_domain_idx
  • alter table tableName drop index pool_domain_idx: 删除索引 pool_domain_idx
  • show index from table: 显示表的所有索引;
  • mysqldump -uroot -pXXXX -h19.168.5.2 -P30118 --databases mgmt >/tmp/mgmt.sql: 导出指定数据库

Demo

查看变量(两种方式)

// 查看事务隔离级别:  方式1
MySQL [(none)]> show variables like "%iso%";
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| tx_isolation | REPEATABLE-READ |
+---------------+-----------------+
1 row in set (0.00 sec) // 方式2
MySQL [(none)]> select @tx_isolation;
+---------------+
| @tx_isolation |
+---------------+
| NULL |
+---------------+
1 row in set (0.00 sec) // 查看最大连接数: 方式1
MySQL [(none)]> show variables like "%max_conn%";
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| max_connect_errors | 100 |
| max_connections | 2000 |
+--------------------+-------+
2 rows in set (0.00 sec) // 方式2:
MySQL [(none)]> select @@max_connections;
+-------------------+
| @@max_connections |
+-------------------+
| 2000 |
+-------------------+
1 row in set (0.00 sec)

设置变量的值

MySQL [(none)]> select @@max_connections;
+-------------------+
| @@max_connections |
+-------------------+
| 3000 |
+-------------------+
1 row in set (0.00 sec) MySQL [(none)]> set global max_connections=4000;
Query OK, 0 rows affected (0.00 sec) MySQL [(none)]> select @@max_connections;
+-------------------+
| @@max_connections |
+-------------------+
| 4000 |
+-------------------+
1 row in set (0.00 sec)

创建数据库

create database if not exists `myTestDB`

创建数据表

create table if not exists `t_user`(
`userid` int(11) not null auto_increment,
`userName` varchar(32) not null DEFAULT '',
`password` varchar(32) DEFAULT null,
`createTime` timestamp not null DEFAULT CURRENT_TIMESTAMP,
`status` smallint(4) default null,
`lastLoginTime` datetime DEFAULT null,
primary key (`userid`),
UNIQUE key `userName`(`userName`)
)ENGINE=InnoDB auto_increment=3 default CHARSET=utf8;

插入数据

在指定的列中插入数据

insert into t_user(userName,password,createTime,status,lastLoginTime) values("Tom","12345","2016-12-12 13:45:12",1,"2016-12-12 13:45:12");
insert into t_user(userName,password,createTime,status,lastLoginTime) values("Lily","12345","2016-12-12 14:45:12",1,"2016-12-12 14:45:12");
insert into t_user(userName,password,status,lastLoginTime) values("Jenny","12345",1,"2016-12-12 14:45:12");

性能优化

索引的设计

Innodb表尽量使用自己指定的主键

Innodb表,主键使用聚合索引,聚合索引会保存完整记录的值,即:数据文件本身就是索引文件,同时数据文件还是一个BTREE结构;

  • Innodb表的主键索引--聚合索引

Innodb的主键应该尽可能的 短

Innodb表中,普通索引都会保存主键的键值,所以主键长度越短越好

  • Innodb表的普通索引: 叶子节点会保存主键的值

问题:为什么选择保存主键值,而不是保存记录的物理地址?

这样的策略减少了当出现行移动或者数据分页时二级索引的维护工作;

二级索引会占用更多的空间,换来的好处是,Innodb在移动行时,无需更新二级索引中的“指针”;

即:以空间换取二级索引的维护工作

使用唯一索引

开启profiles

查看是否开启:默认时没有开启

MySQL [test]> show variables like "%profi%";
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| have_profiling | YES |
| profiling | OFF|
| profiling_history_size | 15 |
+------------------------+-------+

开启:

set profiling=1;

MySQL [test]> show variables like "%profi%";
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| have_profiling | YES |
| profiling | ON |
| profiling_history_size | 15 |
+------------------------+-------+

显示查询性能:

MySQL [test]> show profiles;
+----------+------------+----------------------------------------------------------------------------------+
| Query_ID | Duration | Query |
+----------+------------+----------------------------------------------------------------------------------+
| 1 | 0.00077150 | show variables like "%profi%" |
| 2 | 0.00098675 | select * from pool_configs where pool_id like "7b8f0f5e2fbb4d9aa2d5fd55466dsij%" |
+----------+------------+----------------------------------------------------------------------------------+
2 rows in set, 1 warning (0.00 sec)

索引的选择性

另一种不建议建索引的情况是索引的选择性较低。所谓索引的选择性(Selectivity),是指不重复的索引值(也叫基数,Cardinality)与表记录数(#T)的比值

Index Selectivity = Cardinality / #T

显然选择性的取值范围为(0, 1],选择性越高的索引价值越大,这是由B+Tree的性质决定的。

使用示例:

CREATE TABLE `pool_configs` (
`id` char(32) NOT NULL,
`pool_id` char(32) NOT NULL,
`region_name` varchar(50) DEFAULT NULL,
`domain_id` char(32) DEFAULT NULL,
`value` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `pool_id_index` (`pool_id`),
KEY `domain_index` (`domain_id`),
KEY `pool_domain_value_idx` (`pool_id`,`domain_id`,`value`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |

上面的索引pool_domain_value_idx由3列组成:pool_id,domain_id,value

则该索引的选择性:

MySQL [test]> select count(distinct(concat(pool_id,domain_id,value)))/count(*) as selectivity from pool_configs;
+-------------+
| selectivity |
+-------------+
| 0.2254 |
+-------------+

索引的选择性 与 前缀索引 组合

假设有两列:pool_id, domain_id,长度都为32;

CREATE TABLE `pool_configs` (
`id` char(32) NOT NULL,
`pool_id` char(32) NOT NULL,
`region_name` varchar(50) DEFAULT NULL,
`domain_id` char(32) DEFAULT NULL,
`value` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

计算如下两个选择性

  1. pool_id+domain_id组合:总共64位;
  2. pool_id+domain_id(前8)组合:总共40位;
MySQL [test]> select count(distinct(concat(pool_id, domain_id)))/count(*) as selectivity from pool_configs;
+-------------+
| selectivity |
+-------------+
| 0.9127 |
+-------------+
1 row in set (0.00 sec) MySQL [test]> select count(distinct(concat(pool_id, left(domain_id,8))))/count(*) as selectivity from pool_configs;
+-------------+
| selectivity |
+-------------+
| 0.8563 |
+-------------+

从上面可以发现,使用组合2可以节省将近一半的索引长度,但是选择性并没有降低多少

那在建立索引的时候,就可以这样进行建立:

alter table pool_configs add index poolId_domainId8_idx(pool_id, domain_id(8)); // 只使用前8位

CREATE TABLE `pool_configs` (
`id` char(32) NOT NULL,
`pool_id` char(32) NOT NULL,
`region_name` varchar(50) DEFAULT NULL,
`domain_id` char(32) DEFAULT NULL,
`value` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `poolId_domainId8_idx` (`pool_

这种方式,既满足了选择性较高,且索引长度较短,此种建立索引的方式就是前缀索引:只使用最左前缀的部分列长度;

前缀索引的局限性

前缀索引不能用于ORDER BY和GROUP BY操作,也不能用于Covering index(即当索引本身包含查询所需全部数据时,不再访问数据文件本身)

查看索引使用情况

  • Handler_read_key: 代表行被索引读取的次数,越高越好,很低表名索引没怎么起作用
  • Handler_read_rnd_next: 高,通常表名索引使用不争取,或没有使用索引;
MySQL [test]> show status like "handler_read%";
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| Handler_read_first | 12 |
| Handler_read_key | 12 |
| Handler_read_last | 0 |
| Handler_read_next | 6 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 0 |
| Handler_read_rnd_next | 644 |
+-----------------------+-------+

死锁排查相关指令

查看事务隔离级别

mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set

设置打印死锁日志

set global innodb_print_all_deadlocks = 1;

查看最近一次死锁

show engine innodb status;

然后在打印的日志中,定位到:LATEST DETECTED DEADLOCK

示例

遇到死锁,第一步就是阅读死锁日志。

死锁日志通常分为两部分:

  • 上半部分说明事务1在等待什么锁;
  • 下半部分说明事务2当前只有的锁以及等待的锁;

死锁日志的术语:

  • S锁:共享锁;
  • X锁:排它锁;
  • RECORD LOCKS:记录锁(行锁);
------------------------
LATEST DETECTED DEADLOCK
------------------------
2018-01-05 07:42:47 7f97a6aaf700
*** (1) TRANSACTION:
TRANSACTION 633399987, ACTIVE 21 sec starting index read
//## 事务活跃了21秒,当前状态为读索引 mysql tables in use 1, locked 1
//## 有一个table被使用,表上有一个表锁 LOCK WAIT 2 lock struct(s), heap size 360, 1 row lock(s)
//## 当前事务持有1个行锁 MySQL thread id 83758029, OS thread handle 0x7f97a8823700, query id 1497915714 172.30.29.0 root updating
delete from test where a=2 //###当前事务正在执行该语句
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 3441 page no 4 n bits 72 index `a` of table `test`.`test` trx id 633399987 lock_mode X waiting
//### 事务1正在申请索引a的X锁(排它锁) Record lock, heap no 3 PHYSICAL RECORD: n_fields 2; compact format; info bits 32
0: len 4; hex 00000002; asc ;;
1: len 4; hex 00000002; asc ;; *** (2) TRANSACTION:
TRANSACTION 633399683, ACTIVE 55 sec inserting
mysql tables in use 1, locked 1
4 lock struct(s), heap size 1184, 3 row lock(s), undo log entries 2
MySQL thread id 83757528, OS thread handle 0x7f97a6aaf700, query id 1497916206 172.30.29.0 root update
insert into test (id, a) values (10, 2)
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 3441 page no 4 n bits 72 index `a` of table `test`.`test` trx id 633399683 lock_mode X locks rec but not gap
//### 事务2持有X锁,并且是记录锁 Record lock, heap no 3 PHYSICAL RECORD: n_fields 2; compact format; info bits 32
0: len 4; hex 00000002; asc ;;
1: len 4; hex 00000002; asc ;; *** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 3441 page no 4 n bits 72 index `a` of table `test`.`test` trx id 633399683 lock mode S waiting
//### 事务2正在申请索引a的S锁(共享锁),因为事务1提前申请了该锁,所以造成了死锁 Record lock, heap no 3 PHYSICAL RECORD: n_fields 2; compact format; info bits 32
0: len 4; hex 00000002; asc ;;
1: len 4; hex 00000002; asc ;; *** WE ROLL BACK TRANSACTION (1)

InnoDB目前处理死锁的方法

InnoDB目前处理死锁的方法是将持有最少行级排他锁的事务进行回滚。


Sql慢查询日志

TODO

Mysql优秀博文-好文

mysql事务和锁InnoDB

深入浅出的讲解了数据库死锁原理;

MySQL索引背后的数据结构及算法原理

  • 讲解索引的好文章
  • Innodb和myisam索引实现原理:B+TREE索引、聚合索引、非聚合索引;
  • 最左前缀原理与相关优化

MySQL索引与Index Condition Pushdown


【mysql】MySQL知识整理-死锁分析-性能优化等的更多相关文章

  1. MySQL服务器 IO 100%的分析与优化方案

    前言 压力测试过程中,如果因为资源使用瓶颈等问题引发最直接性能问题是业务交易响应时间偏大,TPS逐渐降低等.而问题定位分析通常情况下,最优先排查的是监控服务器资源利用率,例如先用TOP 或者nmon等 ...

  2. MySQL查询语句执行过程及性能优化(JOIN/ORDER BY)-图

    http://blog.csdn.net/iefreer/article/details/12622097 MySQL查询语句执行过程及性能优化-查询过程及优化方法(JOIN/ORDER BY) 标签 ...

  3. MySQL查询语句执行过程及性能优化-查询过程及优化方法(JOIN/ORDER BY)

    在上一篇文章MySQL查询语句执行过程及性能优化-基本概念和EXPLAIN语句简介中介绍了EXPLAIN语句,并举了一个慢查询例子:

  4. [转] 《高性能HTML5》读后整理的Web性能优化内容

    读后感 先说说<高性能HTML5>这本书的读后感吧,个人觉得这本书前两章跟书的标题完全搭不上关系,或者说只能算是讲解了“高性能”这三个字,HTML5完全不见踪影.个人觉得作者应该首先把HT ...

  5. MySQL 索引知识整理(创建高性能的索引)

    前言: 索引优化应该是对查询性能优化的最有效的手段了.索引能够轻易将查询性能提高几个数量级. // 固态硬盘驱动器有和机械硬盘启动器,有着完全不同的性能特性: 然而即使是固态硬盘,索引的原则依然成立, ...

  6. MYSQL ini 配置文件详解及性能优化方案

    my.ini分为两块:Client Section和Server Section.   Client Section用来配置MySQL客户端参数.   要查看配置参数可以用下面的命令: show va ...

  7. mysql 基础知识整理

    什么是MySQL? MySQL 是一种关系型数据库,在Java企业级开发中非常常用,因为 MySQL 是开源免费的,并且方便扩展.阿里巴巴数据库系统也大量用到了 MySQL,因此它的稳定性是有保障的. ...

  8. 高性能MySQL笔记 第6章 查询性能优化

    6.1 为什么查询速度会慢   查询的生命周期大致可按照顺序来看:从客户端,到服务器,然后在服务器上进行解析,生成执行计划,执行,并返回结果给客户端.其中“执行”可以认为是整个生命周期中最重要的阶段. ...

  9. MySQL高级知识(六)——索引优化

    前言:索引优化的目的主要是让索引不失效,本篇通过相关案例对索引优化进行讲解. 0.准备 创建经典的tb_emp表. DROP TABLE IF EXISTS `tb_emp`; CREATE TABL ...

随机推荐

  1. xdoj-1010(区间问题)

    题目链接 1 扫描一遍不行扫描两遍呗 2 O(n)时间确定cd[i]  [max( a[k]-_min) _min是k+1~n的最小值.i<=k<=n] #include <cstd ...

  2. //生成四位数的验证码--->

  3. C语言--成绩汇总(5班)

    一.成绩列表 第0周成绩:[http://www.cnblogs.com/ranh941/p/7587567.html] 第1周成绩:[http://www.cnblogs.com/ranh941/p ...

  4. Python数据结构与算法(排序)

    https://www.cnblogs.com/fwl8888/p/9315730.html

  5. C++学习(二十七)(C语言部分)之 预处理命令

    结构体 联合 枚举 联合 只能保存最后赋值的结果枚举 所有可能值列出来 预处理命令是在编译前期的阶段 代码-(编译)-->可执行文件(exe)预编译 编译前对代码处理 *1.插入头文件的内容 # ...

  6. hdu3613 Best Reward manacher+贪心+前缀和

    After an uphill battle, General Li won a great victory. Now the head of state decide to reward him w ...

  7. jsp中引入jquery报错:Failed to load resource: the server responded with a status of 404 (Not Found)

    问题描述: 今天自己在搭建spring.springMVC.hibernate框架,搭建完成后,在引入jquery时,发现jquery不管用.我的解决顺序是: 1.检查路径,发现路径没错,另外需要注意 ...

  8. WordPress博客插入直播源

    方法很简单: 找到直播源地址,撰写新文章(可视化切换到文本模式下)插入直播源地址 代码:<iframe id="tv_iframe" width="880" ...

  9. 文件I/0缓冲

    设置stdio流缓冲模式 #include<stdio.h> int setvbuf(FILE *stream,char *buf,int mode,size_t size) int se ...

  10. MySQL Inport--导入数据

    LOAD DATA INFILE导入数据 语法: LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE '' [REPLACE | IGNORE] ...