从数据库引擎的方面考虑(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

引擎在处理查询和连接时会逐个比较字符串中的每个字符,数字型只需要比较一次

提高连接和查询性能,减少存储开销