web和db放在不同的服务器
一主多从,读写分离
一主一从,一从又有多从,读写分离
分库分表(如:按业务分库,按字段取值范围分表/取模分表)
SQL优化
1 分批处理
int pageNo = 1;
int PAGE_SIZE = 100;
while(true) {
List<Integer> batchIdList = queryList('select id FROM `coupon` WHERE expire_date <= #{currentDate} and status = 1 limit #{(pageNo-1) * PAGE_SIZE},#{PAGE_SIZE}');
if (CollectionUtils.isEmpty(batchIdList)) {
return;
}
update('update status = 0 FROM `coupon` where status = 1 and id in #{batchIdList}')
pageNo ++;
}
2 通常<>操作符无法使用索引,可以改成 > union <
7 在Innodb引擎下or无法使用组合索引,可采用union
3 在查询条件列运算会导致索引失效,如 where date_format(create_time,'%Y-%m-%d') = '2019-07-01'
4 避免使用 SELECT *,它会进行全表扫描,不能有效利用索引
15 前后模糊查询like '%keyword%'也无法利用索引
5 join将前面的结果集作为循环数据,再次到后一个表中查询数据。用小结果集驱动大结果集
6 limit用于分页查询时越往后翻性能越差,解决的原则:缩小扫描范围
(不好)select * from orders order by id desc limit 100000,10 耗时0.4秒select * from orders order by id desc limit 1000000,10耗时5.2秒
(好)select * from orders where id > (select id from orders order by id desc limit 1000000, 1) order by id desc limit 0,10耗时0.5秒
8 字段唯一性太低,增加索引没有意义,如:是否删除、性别。
9 如果长度能够满足,整型尽量使用tinyint、smallint、medium_int而非int。
10 如果字符串长度确定,采用char类型。
11 如果varchar能够满足,不采用text类型
12 《阿里巴巴Java开发手册》提出单表行数超过500万行或者单表容量超过2GB,才推荐分库分表。500万这个值仅供参考,并非铁律。
博主曾经操作过超过4亿行数据的单表,分页查询最新的20条记录耗时0.6秒,SQL语句大致是
select field_1,field_2 from table where id < #{prePageMinId} order by id desc limit 20
13 建议将单次查询耗时控制在0.5秒以内,0.5秒是个经验值,源于用户体验的 3秒原则
14 尽量采用timestamp而非datetime。相比datetime,timestamp占用更少的空间