按照锁的粒度分
表锁
表级锁,增删改操作时,会给正张表加锁;
myisam支持表级锁,innodb中默认没有使用表锁,
特点:虽然加锁的开销小,但是并发性能低。
间隙锁
满足某些条件,获取某个区间,即使用范围条件,而不是相等条件检索,innodb为符合条件的已有数据记录加锁,对键值在条件范围内但并不存在的记录为间隙。
行锁
粒度最细的锁,表示只针对当前操作的行进行 加锁。行级锁能大大减少数据库操作的冲突。其加
锁粒度最小,但加锁的开销也 最大。行级锁分为共享锁 和 排他锁。
特点:
粒度最小,发生锁冲突概率最低,并发度最高。
共享锁、排它锁:
共享锁(读锁):
为一个查询预计添加,其他事物可以读,但不能添加排它锁。
select … lock in share mode
排他锁(写锁):
select …for update
为一个查询语句添加排他锁后,其他事务就不能为加锁的数据添加其他锁了。
添加共享锁也是不可以。update,delete,insert 都会自动给涉及到的数据加上排他锁,select 语句默
认不 会加任何锁类型。
Sql 优化
1.查询 SQL 尽量不要使用 select *,而是具体字段
节省资源、减少开销。
2.避免在 where 子句中使用 or 来连接条件
反例:SELECT * FROM user WHERE id=1 OR salary=5000
正例:使用 union all 把两个两个 SQL 结果合并
使用 or 可能会使索引失效,从而全表扫描;
对于or没有索引的salary这种情况,假设它走了id的索引,但是走到salary
查询条件时,它还得全表扫描;
3. 尽量使用数值替代字符串类型
正例
主键(id):primary key 优先使用数值类型 int
性别(gender):0 代表女,1 代表男;数据库没有布尔类型,mysql
推荐使用 tinyint
因为引擎在处理查询和连接时会逐个比较字符串中每一个字符;
而对于数字型而言只需要比较一次就够了;
字符会降低查询和连接的性能,并会增加存储开销;
4. 使用 varchar 代替 char
varchar 变长字段按数据内容实际长度存储,可以节省存储空间;
char 按声明大小存储,不足补空格;
其次对于查询来说,在一个相对较小的字段内搜索,效率更高;
5. 对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by
group by 涉及的列上建立索引
6. 应尽量避免索引失效
6.1 应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引 而进行全表扫描,如:select id from t where num=10 or num=20
6.2 in 和 not in 也要慎用,否则会导致全表扫描,如:select id from t where num in(1,2,3),对于连续的数值,能用 between 就不要用 in ,select id from t where num between 1 and 36.3 模糊查询也将导致全表扫描 select id from t where name like '%abc%'
6.4 应尽量避免在 where 子句中对字段进行函数操作,这将导致引擎放弃使用索引而进 行全表扫描。如: select id from t where substring(name,1,3)='abc'
7. 提高 group by 语句的效率
反例:先分组,再过滤
正例:先过滤,后分组
8. 清空表时优先使用 truncate
truncate table 比 delete 速度快,且使用的系统和事务日志资源少.
delete 语句每次删除一行,并在事务日志中为所删除的每行记录一项。truncate
table 通过释放存储表数据所用的数据页来删除数据.
9. 表连接不宜太多,索引不宜太多,一般 5 个以内
联的表个数越多,编译的时间和开销也就越大 每次关联内存中都生成一个临时表
应该把连接表拆开成较小的几个执行,可读性更高
10. 深度分页问题
反例
select id,name from account limit 100000,10;
正例
select id,name FROM account where id > 100000 order by id limit 10;
11. 使用 explain 分析 SQL 执行计划
使用EXPLAIN关键字可以模拟优化器执行SQL查询语句,从而知道MySQL
是如何处理你的 SQL 语句的。分析你的查询语句或是表结构的性能瓶颈。