MySQL学习笔记

提示:有什么问题欢迎大家指出

目录

  • 其他
  • 查询语句
  • 常用函数
  • DML语言(增删改)
  • DDL语言(增删改)
  • TCL语言(事物控制语言)(多线程)
  • MySQL高级(优化)

其他

//直接输入名字的都不可以用变量替代,名字也都是直接写就行,不用加 ‘ ’
//[Err] 1055 - Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggregated column ‘information_schema.PROFILING.SEQ’ which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
解决办法:SELECT @@sql_mode; SET sql_mode=(SELECT REPLACE(@@sql_mode,‘ONLY_FULL_GROUP_BY’,‘’));
单行注释用#
列也称为字段
`name 表示name是一个普通的字段,不是关键字(~键)
+号在这里只做算术运算,如果字符+数值,会尝试将字符转为数值做运算,转换失败将字符视为0(只有当字符为数字时才能转换成功)
用as起别名(as也可以用空格替代)(别名最好用双引号括起来,不会有歧义)
别名可以代替这段字符,例 concat(年龄 * 10+12,‘姓名’) as 张三 则可以用张三代替concat(年龄 * 10+12,‘姓名’)这段语句
命令行操作 结尾要加; 直接输入MySQL就进来了 不区分大小写
net stop 名字//停止服务 MySQL -hlocalhost -uroot -p123456 //登入,密码是123456
create database mybase//创建库,名字是mybase
drop mybase//卸载 use mybase;//打开库 show databases//显示已有的库
show tables; //查看库里面的表 或者show tables from mybase; 查看mybase里面的表

查询语句

查询语句总语法
select 列名 from 表名 where 筛选 and 继续筛选
group by 列名 #分组查询,按这里的列名中相同字段分组查询
having 筛选 order by 排序语句 limit #这些都是进行分组后的筛选,
基础查询语法:select 查询列表 from 表名;
查询列表可以是,表中的字段,常量,函数,表达式,结果是一个虚拟表格(查询所有)可以同时查询多个
where关键字查询 select 查询列表 from 表名 where 筛选条件;#先定位到表,然后筛选输出
group by分组查询 将要查询的列按列中相同的字段分组查询 支持多个字段分组
select avg(salary),gender#这里写gender,则group by后面也写gender
from 员工表 group by gender #基本格式模板,这里按性别分组查询,结果是所有男性薪水平均值,女薪水平均值
**having ** 放在最后,可进行分组后的筛选 若查询邮箱中包含a字符的,每个部门的平均工资大于12000的,则在上面语句后面加havingacg()>12000并删除where语句即可
order by和排序语句:select 查询列表 from 表名 where 筛选条件 order by 列名 排序关键字; order by放最后
desc 降序 asc 升序 不写默认升序 a asc,b desc 先按a升序,后按b降序(即若a中有一样的数据则按b降序排序)
排序前面要有order by
limit limit 2,5;#表示显示第3条到第7条 limit 5;#表示显示前5条
模糊查询 属于查询语句。一般和通配符搭配使用
列名字 like ‘_a%’ (查询任意一个字符后面接a然后接任意个字符) %为任意多个字符 _ 为单个字符 转义用\或者escape
between 100 and 120 相当于>=100and<=120
in(a,b,c) 查询包括abc中任意一项的值(类型同意或者兼容(可转)不支持通配符)
any或some 和子查询返回的任意一个值比较(例:a>any(查询1,查询2,,, #即a大于括号里任意一个返回值)(用min代替)) all 和子查询返回的所有值比较
exists(a,b,c)效果和in一样,当exists括号里的数据量大于要查询的表时,用exists,exists会返回true或者false(然后将true结果返回)(exists括号里的select
也可以写为select 1或者select ‘x’)
is null 查询值是null的项 =号识别不了null
<=> 相当于is 但is只能与null搭配, <=>可以与任意搭配
连接查询
select 查询列表 form 表1 连接类型(inner,left/right outer)#from后面的表和join后面的要有连接条件
join 表2 on 连接条件 where。。。 #以下都是这个用法,更改连接类型即可
-内连接 inner 和连接查询效果一样,用法不同而已
-外连接(左外 left左边是主表 右外right (加outer)右边是主表 全外full)
查询一个表有,另一个表没有,用外连接,结果为主表所有记录(与从表不匹配(筛选条件)信息为null,只有名字)和从表和主表匹配的记录(查询的信息主要来自于哪个表,那个表就是主表)
全外连接:两个表的交集和两个表不是交集的部分
交叉连接 cross 结果是一个笛卡尔乘积
子查询: 即在一个select中可以再写多个完整的select语句
联合查询:查询多个表,且查询的信息一致(查询的列数,列类型和顺序一致,自动去掉重复,若不想去掉在union后面加all)例:
SELECT name,id FROM employees WHERE name LiKE ‘%a%’ #用于多表间没有连接条件时 这里查询name id两列,下面的语句也必须是两列,且类型是依次对应相等的
UNION #查询id大于90和Email含a的数据,查询的是一个并集,结果以第一个select查询的数据命名
SELECT fname,lid from employees WHERE lid LIKE ‘%a%’
语法 查询语句一 union 查询语句二 union 查询语句三。。。;

常用函数

select distinct #不会查询重复出现的
条件运算符:> < = != <>(不等于) >= <= 逻辑运算符 && || ! and or
//if exists函数 用法:drop procedure if exists 名字 #if exists前面写语句,后面写名字
常见函数:单行函数,组函数 索引都是从1开始 函数可以套多层
desc 表名 #查看表结构
字符函数:concat(a,b) #用于拼接,结果是ab 可以传递多个参数(null和如何字符拼接都是null)
ifnull(a,0) 如果a为null,则返回0
length(a) 返回a的字节长度
upper(a) lower(a)前者将a变为大写,后者变为小写
substr() substring(‘123ddd’,4);返回ddd substring(‘123ddd’,4,2)返回dd #前者和后者是一样的,前者是缩写形式,作用是截取字符段
instr(‘12345’,‘23’); 返回后者在前者的起始位置(结果是2)
trim(‘a’,’ lll ') 去前后所有的a
lpad(‘123’,5,‘1’) 若不满5个则在左边用1填充,若少于5个则右边截断,结果为11123 rpad同理(这里是长度,不是字节数)
replace(‘123456’,‘2’,‘3’)将所有的2换成3
数学函数
round(1.567,2);四舍五入 后面参数表示保留小数点后两位,结果是1.57
ceil()向上取整()返回大于等于它的最小整数 floor返回小于等于它的最小整数
truncate(1.6999,1)截断 小数点后保留1位,结果是1.6
mod(a,b) 取余,和%一样相当于(a-a/bb)
日期函数
now() 返回当前日期时间
curdate() 返回日期,不包含时间
curtime 返回时间,不包含日期
year(‘1999’) year(now()) 返回当前年份 月是month 英语月是monthname 其他类似
str_to_data(‘1998-3-2’,‘%Y-%c-%d’) 将字符转为日期
date_format(now(),‘%年-%c月-%d日’) 将日期转为字符
日期格式:Y表示四位数年份,y表示两位数 月两位数m(单位数c) 日d 24小时H(12h) 分i 秒s
其他函数
database()
user
version
返回当前版本,库
分组函数 avg(列名)from 表名 即求出并显示列中的平均数
sum(salary)求和 sum(distinct salary) 不计算重复的,以下皆可用distinct
avg(salary)平均值
max(salary)最大值
min(salary)最小值
count(salary)非空值的个数 以上都忽略null
count(
)统计所有,有一个不为null,则计入 count(里面可以写任何值)和*一样,一般写1

DML语言(增删改)

//默认自动提交,但可以进行事务操作
插入语法一:insert into 表名(列的名字。。。) values (值。。。);
例:insert into beauty(id,name,sex)values (13,‘王五’,‘男’),values (14,‘王三’,‘男’);
#可以为空的可以不写,列的名字可以和对应值可以不写,例的顺序可以颠倒,可以省略列名,默认所有列名
插入语法二:insert into 表名 set 列名=值,列名=值。。。; #不支持同时添加多个数据
#可以在方式一后面接select语法,方式二不行

修改单表的记录:语法:update 表名 set 列=新值,列=新值。。。 where 筛选条件 先筛选后修改
例:update beauty set phone=‘123’ where name like ‘王%’; 修改beauty 表中性王的电话为123
修改多表的记录:update boys inner join beauty b on bo.id=b.boyfriend_id
set b.phone=‘114’ where bo.boyname=‘张三’; #修改张三的奴朋友的手机号为114

删除方式一:delete from 表名 where 筛选条件 select 。。。
多表删除 delete 表1的别名,表2的别名
from 表 inner join 表2 别名 on 连接条件 where 筛选条件
例:delete b,bo
from beauty b inner join boys bo on b.boyfriend=bo.id where bo.boyname=‘张三’;
方式二:语法:truncate table boys; 删除表中全部数据
truncate删除效率高一丝,如果删除的表中有自增长列,用delete删除再插入从断点(原有5,删除再加依为5)开始,truncate从1开始
delete删除有返回值 truncate删除不能回滚,delete删除可回滚

DDL语言(增删改)

//DDL语句的操作一旦执行都会自动提交,所以事务(回滚)的操作对它无效
创建库 create database 库名; create database if exists 库名;#已存在则不创建
修改库 修改文件夹的名字
修改库的字符集:alter database 库名 character set gbk;
库的删除 drop database 库名;
查看表 desc 表名;

创建表 create table 表名(列名 列的类型);
例:create table book(id int,bname varchar(20));
查看表 desc 表名; show tables;查看当前库的所有表
表的删除 drop table book_author;
表的复制 复制结构 create table copy(新名字) like author; 复制结构和数据 create table copy2 select * from author;#即复制select查询到的数据
表的修改 语法 alter table book(表名)change /modify/add /drop column 列名 (类型,约束)
列名修改:alter table book(表名) change column id book_id(前为原列名,后为新列名) 类型(新类型);
//后面必须加类型,比如varchar(10)
列的类型/约束的修改:alter table book(表名) modify column book_id int not null (约束)
列的约束的添加:alter table book(表名)add 约束
添加新列:alter table author(表名) add column annual(列名) double(类型);
删除列:alter table author(表名) drop column annual(列名);
修改表名:alter table author(表名)rename to book_author(新表名);
//枚举是一种表,可以限制表中列的值,可以从表中得到表中的字符
常见数据类型和约束
数据类型:可以在后面int(7)zerofill 表示长度为7,不足则填充0
-整型:tinyint 有符号-128~127 无符号0~255,字节1 smallint -32768~32767 字节2 mediumint 字节3 int/integer 字节4 bigint 字节8
-小数:语法,float(m,d) m,d可以省略m是整数加小数的总长度,d是小数点后位数
float 字节4 double 字节8(前两个m,d根据传入数的大小匹配) 定点数dec(精度高)(m默认10,d默认0)
-字符型:char(m) varchar(m) m指最多字符数,varchar(m)分配空间是可变的,传入两个字符就分配2个字符的空间,而char固定m,但char效率高
枚举 create table tab(c1 enum(‘a’,‘b’)); insert into tab values (‘a’); 这里的值只能是枚举中定义的a和b(大写也可以),如果是别的值会报错
set(集合) create table tab(c1 set(‘a’,‘b’)); 大写也可以n insert into tab values (‘a,b’);也可以
-日期:timestamp字节4,受时区等影响(1970~2038) datetime字节8
约束:限制表中的数据的准确性和可靠性
not null 该字段的值不能为空
default 该字段有默认值
primary key保证该字段的值具有唯一性且非空(一个表至多一个)
unique 唯一性但可空(一个表可有多个)
check 检查约束,但MySQL不支持
foreign key外键,用于限制两个表的关系,在从表添加外键约束用于引用主表中某列的值(即主表中的值有副表的值对应,例设置主表学生的专业编号为20,则专业表(副表)中应该有编号为20的专业)
主表的关联列必须是主键或者unique,在添加约束时,从表最好是空的,不然可能添加失败,因为一般是先往主表添加数据再添加从表 主表也最好为空
列的约束,外键约束不支持 表的约束除了非空都行
语法:create table 表名(列名 列的类型 列的约束,列名 列的类型 列的约束,。。。表的约束 unique(列名,列名));#直接在创建表中unique(列名,列名)给列添加约束
在添加约束时添加约束名,例:#去掉 constraint 名字 就是添加约束的语法-(建立外键约束)
alter table 表名 add constraint 名字 foreign key(majorid) references major(id)#这里的majorid是副表对应的列,major是主表
标识列:自增长列(即当你在更新其他列时,该列自动更新)标识列必须和key搭配(unique也是key),一个表至多一个标识列
添加方法:在约束后面加auto_increment,起始值可以设置,默认null为1 alter table 表名 _a AUTO_INCREMENT=1000//设置为1000
set auto_increment_increment=3 设置步长为3(默认为1)每执行一次在每隔2个列后增加一列即按147这样增加
修改表时可以删除增加标识列
//查看外键约束及约束名show create table autotable3; 在constraint后面的是约束名
//删除外键约束ALTER TABLE autotable3 drop FOREIGN KEY 约束名;

TCL语言(事物控制语言)(多线程)

//对于回滚,在一个表的创建到删除中的所有语句都不能回滚,即从create table 到 drop table 中写的所有语句都不能回滚,如果没有删除表,则可以回滚
一个或者一组sql语句组成一个执行单元,这个单元为整体要么全部执行要不全部不执行,这种称为事物(多线程)
回滚即回到最初状态(已经提交的数据不可以回滚)
ACID表示事物的属性分别是:原子性(整体性),一致性(必须从一个一致性状态变为另一个一致性状态),隔离性(这个事物不会被其他事物干扰),永久性(事物对数据的改变是永久的)
set autocommit=0; #开启事务
select,delete,insert,update这些隐式事务(即不加开启结束事物标志的sql语句)
commit; #结束事务
rollback;#回滚事物,即回到事物没有执行之前
四种隔离级别 MySQL支持四种默认repeatable read,Oracle支持read commited,serializable两种 默认read commited
read uncommitted 以下问题都会出现 允许事务读取未被其他事物提交的变更.
read commited 可以避免脏读 只允许事务读取已经被其它事务提交的变更
repeatable read 只可能出现幻读 确保事务可以多次从一个字段中读取相同的值.在这个事务持续期问,禁止其他事物对这个字段进行更新
serializable 确保事务可以从一个表中读取相同的行.在这个事务持续期问.禁止其他事务对该表执行插入.更新和删除操作.所有并发问题都可以避免,但性能十分低下.
不可重复读(刷新后读的数据与前面不一样(你读取,然后别人修改了数据你刷新了))
脏读:你读取到别人提交当未结束的数据,然后别人回滚,你刷新了
幻读:你读取了一个表,然后别人插入了新列,你再读取
查看当前隔离级别 select @@tx_isolation;
设置隔离级别 set session(加global表示设置全局) transaction isolation level read commited
设置保存点 savepoint a; 返回保存点 rollback to a;
视图:相当于封装语句,相当于一个表(但不占用实际内存空间)
创建视图语法:create view 名字(随便起)as 查询语句
调用视图语法:select * from 视图名字 然后根据视图的查询结构继续写查询语句
视图的修改:create or replace view 名字 as 查询语句
方式二:alter view 名字 as 查询语句
删除语句:drop view 名字
具备以下特点的视图不允许修改(更新)
1.包含distinct,group,by,having,union,union all,join关键字的sql语句
2.常量视图,包含常量的视图
3.select中包含子查询
4.from一个不能修改的视图
5,where子句的子查询引用了from子句中的表
-truncate 不支持回滚,delete支持
//使用变量时一定要加@
变量
系统变量:全局变量(global)服务器每次启动都会给变量赋予默认值,会话变量(session)(当前连接)
查看变量:show session variables like ‘%char%’;
select @@global.变量名
为变量赋值:set global 变量名=值;
select @@global.变量名=值
自定义变量:
1.用户变量,针对于当前会话(连接)有用 使用时要在变量名前加@
声明并初始化:set @名字=值;或set @名字:=值;或select @名字:=值;(赋值也用这个)
赋值:select count() into @变量名 from 表名 #表示将count()的值赋予变量
查看 select @变量名;
2.局部变量:仅在begin end中的第一句话
声明:declare 变量名 类型 default 值;或declare 变量名,类型
例:declare i int default 1; 相当于Java中 int i=1;
赋值和用户变量一样
方法与存储过程
//使用存储过程时,参数名和传入的变量名要一致,不然会全部为null
//在使用存储过程中要用delimiter设置结尾符号,以区分循环的结尾和语句的结尾
存储过程和函数和Java中的方法差不多(如果sql语句只有一句,则begin end可以省略)
创建语法:create procedure 名字(参数模式 参数名字(随便起) 参数类型)begin sql语句 end
参数模式 参数名字 参数类型举例:in st varchar(20)
参数模式 in 该参数需要调用方法传入值(普通参数,不可返回) out 该参数可以作为返回值 inout 该参数既可以传入有可以作为返回值
调用 call 名字(out ccc int);
例:delimiter $
create procedure mymethod() begin sql语句 end $
在接受返回类型时:例call mymethod(@名字)$ 名字随便起用于接受返回值
select @名字$
drop procedure 名字 删除存储过程
show create procedure 名字 查看存储过程信息
函数:有且只有一个返回值 如果函数体只有一条语句,则begin end可以省略(可以通过delimiter设置存储过程的结尾)
语法:create function 名字(参数列表(只有两个部分)) returns 返回类型
begin 函数体 end
调用:select 函数名(参数) 会返回并打印参数
show create function 名字 查看函数信息
drop function 删除函数
流程控制结构(循环判断语句)
流程控制函数
if(10>5,‘大’,’小‘) 这段语句会返回字符‘大’
-case用法一(类似于Java switch case)
case 变量 when 常量 then 语句;,值(不用;) when 常量 then 语句;,值 else 语句;值 end and as 。。。别名
-语法:case用法2(类似于if else)
case when 条件 then 结果 when 条件 then 结果 else 结果 end
-分支结构 if函数 case函数,见常见函数
可以作为独立的语句使用,但只能放在begin end中(以下都只能放在begin end中)
if分支 语法
if 条件1 then 语句; elseif 条件2 then 语句2; end if
//循环结构中加入查询输出语句会报错,因为每一次循环都会查询,显示不了(比如在无限循环中加入show函数)
-循环结构
循环控制iterate 类似于continue leave 类似于break,结束当前循环
while 循环条件 do 循环体; end while 标签; #先判断后执行,相当于while
标签 loop 循环体; end loop 标签; #无条件死循环
标签 repeat 循环体;until 结束循环的条件 end repeat 标签; #先执行后判断 相当于do while

MySQL高级(优化)

在使用MySQL之前先检查乱码问题,因为如果有乱码,在你建立库后再解决乱码问题,已经建立的库依然会有乱码
MySQL有些功能是关闭的,比如错误日志,查询日志
1.开启慢查询日志,找到慢的sql,2.explan 3.show profile 4.sql数据库服务器的参数调优
sql执行顺序 from on join where groupby having select distinct orderby limit
手写顺序 select from join on where and group by having order by limit
inner join 交集 left join 左表(当连接条件中右为null时,结果为左表除交集) right join 右表(当连接条件中左为null时,结果为右表除交集)
full outer join 全集(当连接条件中右为null或者左为null时,结果为全集除交集)
覆盖索引:查询列被所建索引覆盖(即select 后接的列的顺序和建立索引顺序相同,select后面的列的数量<=复合索引中列的数量)
//建立索引的注意事项 1.查找哪个列就建哪个列的索引,有带头大哥最好(索引包含三个列,实际只查找一个列,效果不如只建立一个列的索引)
索引:索引是一种数据结构(一般是B树),提高查找效率,类似字典(即对数据进行排序,按索引查找)索引存储在文件(磁盘上)
B树:一个结点的子结点树不超过树的阶数,
缺点:占用空间,降低更新表的速度(会更新表和索引中的值),
优点:io成本,CPU消耗低,排序,查找快
唯一索引,索引号唯一
语法:create unique(#表示是唯一索引,可以不加) index 名字 on 表(字段);写一个字段是单值索引,写多个是多值索引
或者 alter 表 add unique index 名字 on (字段)
删除 drop index 名字 on 表
查看 show index from 表
-需要建立索引的情况
1.主键自动建立唯一索引 2.频繁作为查询的字段应建立索引 3.外键关系应该建立索引
4.查询中统计或者分组字段 5.where条件里用不到的字段不创建索引 6.排序加索引会提高排序速度
不需要建立索引的情况
1.表记录太少 2.频繁更新不建议创建索引 3.表中有许多重复且平均分配的数据
性能分析(explain)
cpu负担重,io内存不足 服务器硬件性能弱(缓冲空间小?)
optimizer与预想不一致
----explain 使用explain关键字可以模拟优化器执行sql查询语句,从而知道MySQL是如何处理你的sql语句的,从而分析性能瓶颈
语法:explain sql语句
使用explain输出包含的信息:
id:有三种值:1.id相同:执行顺序上到下 2.id不同:id值大的优先级高越先被执行 3.id值包含相同和不同。
select_type:查询类型:普通查询(simple),联合查询,子查询(primary最外层和subquery子)deriver(from列表中包含的子查询),union result(从union表中获取结果的select)等等
table
type:system—const—eq_ref—ref—range—index—all(左最好右最差(性能)最少达到range级)
system(单表单行)—const(通过一次索引就能找到)—eq_ref(唯一索引,一索引一记录)—ref(一索引多记录(行))—range(检索给定范围的行,例:在where后使用<>between)—index(全索引)—all(全表)
possible_keys(可能应用的索引) key(实际用到的索引,若使用了覆盖索引,则该索引只显示key不显示possible_keys中) key_len(索引字段最大可能长度,长度越段越好)
ref(哪些列或者常量用于查找索引列上的值) rows(大致估算出找到所需记录所需要读取的行数)
extra(其他信息)using filesort:在使用不上定义的索引时会使用文件排序,说明出现了问题,影响性能
using temporary 非常影响性能,使用了临时表,一般出现在group by中
using index 使用了覆盖索引,说明性能不错
impossible where where后的条件有错误

左连接建右表索引,右连接建左表索引(不改索引改表的位置也可)
–(用内部(副表)建立索引驱动优化外部(主表))

避免索引失效,(以下指在where后面使用的列)
带头大哥不能死,中间兄弟不能断,索引列上少计算,范围之后全失效,like符号写左右,覆盖索引不写*,is null ,is not null不能用,or少用
1.建立复合索引,在使用复合索引时,如果没有使用到最左的列(建立时顺序在最左端)则会导致索引失效
2.最好不要直接使用13索引列(即跳过中间索引列),会导致只使用到部分索引
3.不在索引列上做任何操作(计算、函数、(自动or手动)类型转换),会导致索引失效而转向全表扫描(where后面使用的列就是索引列)
4.范围之后全失效(条件给的是一个范围,则范围之后的索引列失效(不是等于的都是范围,orderby也是范围))
5.尽量使用覆盖索引(索引列和查询列一致或者包含),减少使用select *
6.mysql在使用不等于(!=或者<>)的时候无法使用索引会导致全表扫描
7.is null ,is not null 也无法使用索引
8.like以通配符开头(‘%abc…’ )mysql索引失效会变成全表扫描的操作(可以使用通配符结尾)(解决办法:使用覆盖索引可以在两边使用通配符)
9.字符串不加单引号索引失效
10.少用or,用它来连接时会索引失效
提高order by速度
1.不要使用select* 2.尝试提高sort_buffer_size和max_length_for_sort_data(不要超过前者)
orderby能使用index(避免fileresort)(见图片)(groupby和orderby一样,但少用having即可)
1.带头大哥不能死,中间兄弟不能断(从where到orderby中间兄弟不断) 2.必须按顺序升序排序(因为默认是升序) 3.带头大哥是常量(where定义的常量)
慢查询,默认关闭,
SHoW VARIABLES LIKE’%slow_query_log%';#查询状态
set global slow_query_log=1; #开启慢查询(重启MySQL失效)
SHoW VARIABLES LIKE‘long_query_time%’#查询阙值(大于这个值的被定义为慢查询(不包括等于))
set global long_query_time=3; #设置阙值(需要重新连接或者新开一个会话才能看到修改)
select sleep(4); #睡4秒
cd/var/lib/mysql
cat atguigu-slow.log #找到并打印超过阙值的sql语句
MySQLdumpslow工具的使用
得到返回记录集最多的10个SQLmysqldumpslow -s r-t 10 /var/lib/mysql/atguigu-slow.log
得到访问次数最多的10个SQLmysqldumpslow -s c -t 10 /lvar/lib/mysql/atguigu-slow.log
得到按照时间排序的前10条里面含有左连接的查询语句mysqldumpslow -s t -t 10 -g “left join”/var/lib/mysql/atguigu-slow.log
另外建议在使用这些命令时结合│和more 使用,否则有可能出现爆屏情况mysqldumpslow -s r -t 10 /var/lib/mysql/atguigu-slow.log | more
s:是表示按照何种方式排序; c:访问次数 l锁定时间 r:返回记录 t:查询时间 al:平均锁定时间 ar:平均返回记录数 at:平均查询时间 t:即为返回前面多少条的数据; g:后边搭配一个正则匹配模式,大小写不敏感的;
加入开启慢查询后创建函数报错,则用下面代码
show variables like ‘log_bin_trust_function_creators";
set global log_bin_trust_function_creators=1;
show profile:用于分析当前会话语句资源消耗情况,默认关闭并保存最近15次运行结果
show variables like‘profiling’;
set profiling=on;
show profiles; #查询最近运行的语句的执行时间
show profile cpu,block io for query 3; #看第三条语句的资源消耗情况(show profiles查询会给出一个id)(一条sql语句的生命周期)
还可以看其他的信息,比如all(所有),memory(内存)(block io 指io)
若查询结果出现以下情况,则需要优化
converting HEAP to MyISAM查询结果太大,内存都不够用了往磁盘上搬了
Creating tmp table创建临时表 用完再删除 拷贝数据到临时表
Copying to tmp table on disk把内存中临时表复制到磁盘,危险!!!
locked
测试环境才能使用 全局查询日志

读写锁用myisam引擎,偏读锁 行锁采用innodb引擎(引擎默认行锁),开销大,加锁慢,会出现死,发生冲突概率低,并发度高
读锁(当前会话只能读这个被锁了的表(不能写这个表),其他会话可以读所有表,但要写这个被锁的表会阻塞,直到锁释放会修改成功),
写锁(当前会话只能查看和修改加了锁的表,其他会话查询和更新加了锁的表会阻塞)
行锁,当两个会话操作同一行时会出现阻塞,若操作不同行则没有问题
索引失效会导致行锁会变成表锁
间隙锁:若使用范围条件,则innodb会给所有在条件内的项加锁,不管这项存不存在(即若范围为1~4,而实际存在134,在执行这个范围语句时没有结束事物则会导致另一会话在增加2时等待)
show open table; #查看有无锁
lock table 名字 read,名字 write;#给表加锁,read是读锁,write是写锁
unlock tables; #释放锁
show status like’table%’ #查看当前锁的状态tablelocksimmediate表示表级锁定的次数 tablelockswaited表示出现表级锁定而发生等待的次数,此值高说明出现锁争用的情况
手动加行锁,悲观锁:begin ;select * from 表 where 条件 for update; #给查找到的行加锁
show status like ‘innodb_row_lock%’; #查看当前锁的状态,current_waits表示正在等待锁的数量 avg表示每次等待锁的平均时间 lock_waits表示启动后总等待次数
乐观锁:一般使用这个锁,并发高
----------主从复制 主机MySQL复制到从机
版本一致,

你可能感兴趣的:(Java自学系列,mysql,数据库,学习)