Innodb和MyISAM的区别 - Innodb支持事务,MyISAM不支持,Innodb针对每条SQL语句都默认封装为事务,自动提交,这样会影响执行速度 - Innodb支持外键约束,MyISAM不支持。所以对于一个包含外键的innodb表转换为MyISAM会失败 - Innodb采用的时聚集索引,数据文件和索引绑定,必须有主键,通过主键查询效率很高;但是辅助索引需要两次查询,因此在Innodb中主键不应该过大;MyISAM采用的是非聚集索引,所以数据文件分离 - innodb不保存数据的总行数,执行`select count(*)`需要全表扫描;而MyISAM使用一个变量保存了表的总行数,所以执行`count(*)`查询时速度很快 - Innodb5.5-不支持全文索引,MyISAM支持全文索引,查询效率上MyISAM高
选择依据: - 如果没有特殊要求,使用默认的innodb即可 - MyISAM:以读取和插入为主的应用,比如博客系统、新闻网站等。搜索引擎采用NoSQL类型的数据库ES提供 - Innodb:更新删除操作效率要求较高或者要求保证数据的完整性,同时考虑并发量要求高的场景下使用,例如OA之类的管理系统。因为支持事务和外键所以能够很好的保证数据完整性
## 表级锁
锁的颗粒度为整个表 `lock tables 表名称 read/write`,其中read是共享锁,一旦锁定则共享读取数据,write是排他锁,只有加锁的客户端可以读写,其它客户端不可读也不可写 解锁 `unlock tables`
## 行级锁
锁的颗粒度为表中的特定的一行或者多行 共享锁`select * from 表名称 where 条件 lock in share mode;` 排他锁`select * from 表名称 where 条件 for update;` 注意:所谓的行锁并不是直接锁定特定行的数据,实际上是锁定一个子范围,所以也称为间隙锁。例如`select * from tb_student where id<20 lock in share mode`实际上并不是锁定id<20的现有数据,而是锁定id<20的范围,例如插入id为18的新记录失败
## 死锁问题
死锁是指两个或多个事务在同一资源上相互占用,并请求锁定对方的资源,从而导致恶性循环的现象。 常见的解决死锁的方法 - 如果不同程序会并发存取多个表, 尽量约定以相同的顺序访问表,可以大大降低死锁机会。 - 在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁产生概率; - 对于非常容易产生死锁的业务部分,可以尝试使用升级锁定颗粒度,通过表级锁定来减少死锁产生的概率; 如果业务处理不好可以用分布式事务锁或者使用乐观锁 - update tb_users set salary=? where id=1 - update tb_users set salary=?,version=2 where id=1 and version=1 [version是一个额外的列,用于记录当前行的版本号]
[mysqld] port=3306 max_connections=200 max_connect_errors=10 character-set-server=utf8mb4 default-storage-engine=INNODB default_authentication_plugin=mysql_native_password [mysql] default-character-set=utf8mb4 [client] port=3306 default-character-set=utf8mb4
# 查询缓存
可以缓存select语句的查询结果,以浪费内存为代价换取高执行效率
配置参数query_cache_type
- 0 不开启
- 1开启缓存,默认缓存所有select,如果需要不缓存则需要在select语句中添加sql-no-cache提示放弃缓存
- 2开启缓存,默认都不缓存,需要在sql语句中添加select sql-cache主动缓存
需要添加mysql配置文件,windows上my.ini,Linux上my.conf
```ini
query_cache_type=1
```
查看MySQL是否开启缓存
```mysql
show variables like 'query_cache_type';
```
配置打开查询缓存大小
```
mysql set global query_cache_size=64*1024*1024; -- 配置查询缓存为64M show variables like 'query%'; ``` 将查询结果进行
```mysql
select sql_cache * from tb_users where ...;
```
重置缓存
```mysql
reset query cache;
``
` ## 应用中的问题
1、应用程序不应该关心query cache的使用情况,因为使用查询缓存需要修改数据库的配置信息,所以实际上是由DBA决定的
2、缓存是以SQL语句为key进行存储的,因此即使SQL语句功能相同,然是如果多一个空格或者大小写有差异都会导致匹配不到缓存数据