==总结
EXISTS语法:
SELECT ... FROM table WHERE EXISTS (subquery)
该语法可以理解为:将主查询的数据,放到子查询中做条件验证,根据验证结果(TRUE或FALSE)来决定主查询的数据结果是否得以保留。
SELECT 1
或select 'X'
,官方说法是实际执行时会忽略SELECT清单,因此没有区别优化原则:
通过如下语句查看开启状态
show variables like '%slow_query_log%';
开启方法
set global slow_query_log = 1;
使用上面的语句开启慢查询日志只对当前数据库生效,重启MySQL失效。
如果需要永久生效,修改my.cnf
/my.ini
后重启MySQL
slow_query_log = 1 slow_query_log_file = /var/lib/mysql/$-slow.log
尽量不要这么做,降低性能!!!
查询
show variables like '%long_query_time%';
修改
set global long_query_time = 3;
设置之后需要重新连接或新开一个会话才能看到修改的值
show global status like '%slow_queries%';
mysqldumpslow [ OPTS... ] [ LOGS... ] s:是表示按照何种方式排序; c:访问次数 l:锁定时间 r:返回记录 t:查询时间 al:平均锁定时间 ar:平均返回记录数 at:平均查询时间 t:返回前面多少条的数据 g:后面搭配一个正则匹配模式,大小写不敏感
查看状态
show variables like 'profiling';
查看结果
show profiles;
诊断SQL
show profile cpu,block io for query ${Num};
上面为常用参数
参数:
类型 | 含义 |
---|---|
ALL | 所有的开销信息 |
BLOCK IO | 块IO相关开销 |
CONTEXT SWITCHES | 上下文切换相关开销 |
CPU | CPU相关开销信息 |
IPC | 发送和接收相关开销信息 |
MEMORY | 内存相关开销信息 |
PAGE FAULTS | 页面错误相关开销信息 |
SOURCE | Source_function,Source_file, Source_ line相关开销信息 |
SWAPS | 交换次数相关开销的信息 |
执行上面的SQL后尽量不出现下面的东西
方法一、命令
开启
set global general_log=1;
设置输出方式
set global log_output='TABLE'
此后,你所编写的sq|语句,将会记录到mysq|库里的general_log表, 可以用下面的命令查看
查看方式
selet * from mysql.general_log;
方法二、配置文件启用
在MySQL的my.cnf
/my.ini
中添加如下
# 开启
general_log=1
# 记录日志文件的路径
general_log_file=/path/logfile
# 输出格式
log_output=FILE
按数据类型分类:
**读锁(共享锁):**针对同一份数据,多个读操作可以同时进行而不会相互影响
**写锁(排他锁):**当写操作没有完成前,阻断其他写锁和读锁
按对数据操作的粒度分:
表锁;
行锁;
添加表锁
lock table 表名 read(write), 表名2 read(write), 其他
查看表上加过的锁
show open tables;
解锁
unlock tables;
通过检查table_locks_waited
和table_locks_immediate
状态来分析系统上的表锁定
show status like 'table%';
这里有两个状态变量记录MySQL内部表级锁定的情况,两个变量说明如下:
Table_locks_immediate:产生表级锁定的次数,表示可以立即获取锁的查询次数,每立即获取锁值加1;
Table_locks_waited:出现表级锁定争用而发生等待的次数(不能立即获取锁的次数,每等待一次锁值加1),此值高则说明存在着较严重的表级锁争用情况;
事务是由一组SQL语句组成的逻辑处理单元,事务具有以下4个属性,通常简称为事务的ACID属性。
原子性(Atomicity) :事务是一个原子操作单元,其对数据的修改,要么全都执行,要么全都不执行。
一致性(Consistent):在事务开始和完成时,数据都必须保持一致状态。这意味着所有相关的数据规则都必须应用于事务的修改,以保持数据的完整性;事务结束时,所有的内部数据结构(如B树索引或双向链表)也都必须是正确的。
隔离性(Isolation):数据库系统提供一 定的隔离机制,保证事务在不受外部并发操作影响的“独立”环境执行。这意味着事务处理过程中的中间状态对外部是不可见的,反之亦然。
持久性(Durable):事务完成之后,它对于数据的修改是永久性的,即使出现系统故障也能够保持。
更新丢失(Lost Update):两个事务同时更新一行数据,最后一个事务的更新会覆盖掉第一个事务的更新,从而导致第一个事务更新的数据丢失的;
脏读(Dirty Reads):读取到了已修改尚未提交的数据
不可重复读(Non-Repeatable Reads):在同一事务中,两次读取同一数据,得到内容不同,也就是有其他事务更改了这些数据
幻读(Phantom Reads):一个事务在执行过程中读取到了另一个事务已提交的插入数据;即在第一个事务开始时读取到一批数据,但此后另一个事务又插入了新数据并提交,此时第一个事务又读取这批数据但发现多了一条,即好像发生幻觉一样。
事务隔离级别 | 读数据一致性 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|---|
读未提交(read-uncommitted) | 最低级别,只能保证不读取物理上损坏的数据 | 是 | 是 | 是 |
读已提交(read-committed) | 语句级 | 否 | 是 | 是 |
可重复读(repeatable read) | 事务级(MySQL默认) | 否 | 否 | 是 |
可序列化(serializable) | 最高级别,事务级 | 否 | 否 | 否 |
查看数据库的隔离级别
# MySQL5.x
show variables like '%tx_isolation%';
# MySQL8.0
show variables like '%transaction_isolation%';
默认未提交前锁定一行
语法
# 显式开启事务
begin;
select * from table_name where xxxx for update;
# 提交事务
commit;
关闭自动提交 # 1为自动提交 set autocommit=0;
show status like 'innodb_row_lock%';
状态量 | 解释 |
---|---|
InnoDB_row_lock_current_waits | 当前正在等待锁定的数量**(重要)** |
InnoDB_row_lock_time | 从系统启动到现在锁定总时间长度**(重要)** |
InnoDB_row_lock_time_avg | 每次等待所花平均时间; |
InnoDB_row_lock_time_max | 从系统启动到现在等待最常的一次所花的时间 |
InnoDB_row_lock_waits | 系统启动后到现在总共等待的次数**(重要)** |
当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB 会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但并不存在的记录,叫做**“间隙(GAP)”**,
InnoDB也会对这个“间隙”加锁,这种锁机制就是所谓的间隙锁(Next-Key锁) 。
因为Query执行过程中通过过范围查找的话,他会锁定整个范围内所有的索引键值,即使这个键值并不存在间隙锁有一个比较致命的弱点,就是当锁定一个范围键值之后,即使某些不存在的键值也会被无辜的锁定,而造成在锁定的时候无法插入锁定键值范围内的任何数据。在某些场景下这可能会对性能造成很大的危害。
InnoDB存储引擎由于实现了行级锁定,虽然在锁定机制的实现方面所带来的性能损耗可能比表级锁定会要更高一些, 但是在整体并发处理能力方面要远远优于MyISAM的表级锁定的。当系统并发量较高的时候,InnoDB的整体性能和MyISAM相比就会有比较明显的优势了。
但是,Innodb的行级锁定同样也有其脆弱的一面,当我们使用不当的时候,可能会证Innodb的整体性能表现不仅不能比MyISAM高甚至可能会更差。
优化建议