从数据库引擎的方面考虑(InnoDB、Myisam、NDB、Falcon等等):
InnoDB(行锁):
行锁:仅支持一个事务操作数据库表的某一行数据,当一个事务拿到行锁,另一事物无法操作此行数据包括select
优点:粒度小、支持CRUD事务
缺点:获取锁和释放锁需要花费资源、容易发生死锁
共享锁(读):
允许多个事务共用一行数据,在修改表数据时不能使用此情况
排他锁(写,默认):
一个事务拿到行锁后,另一事务无法操作查询此行数据,直到提交或回滚释放锁。容易发生死锁
优化:
1.控制事务的大小不宜过大,否则会占用行锁时间过长,影响其他事务的效率
2.尽可能使用索引作为过滤条件,提升sql操作的效率,减少事务花费的时间
3.合理设计索引
4.业务允许的话,可以适当降低隔离级别
Myisam(表锁):
优点:获取锁和释放锁快,不会出现死锁
缺点:不能使用事务,粒度大,适用于表仅用来读的表结构
SQL语句优化:
1.尽量避免使用 * 全字段查询,仅查询需要用到的字段
例: 错误:select * from user ; 改为:select id,name from user;
2.尽量使用有索引的字段作为查询(where)条件和排序(order by)条件
3.尽可能避免使用复杂的join连接查询
4.避免在where条件上作null的判断,可以给需要作null的判断上给一个0默认值,判断是否为0即可
5.避免在where条件上使用 != 或<>操作符,这都会导致放弃索引作全表扫描
6.避免在where条件上使用or作条件拼接,这会导致放弃索引作全表扫描
可以用union 或 union all替代or
例: 错误:select * from user where id = 3 or id = 4; 改为:select * from user where id = 3 union select * from user where id = 6
7.使用exists替代in 和 not in 作条件,in和not in也会导致放弃索引
例: select * from user where id in (select id from group where score > 60) select * from user where exists (select 1 from group where score > 60 and user.id=group.user_id )
8.避免在where条件上对字段做算术运算,这会导致放弃索引作全表扫描
例: 错误:select * from user where age*2 = 60; 改为:select * from user where age = 60/2;
9.避免在where条件上对字段做函数操作,这回导致放弃索引作全表扫描
例: 错误:select * from user where substring(name,1,2) = '陈'; 改为:select * from user where name like '陈%';
10.尽量设计数字型字段(类似状态state,id这一类纯数字),而不是字符型varchar
引擎在处理查询和连接时会逐个比较字符串中的每个字符,数字型只需要比较一次
提高连接和查询性能,减少存储开销