数据库优化
1.硬件
2.系统配置
3.数据表结构
4.sql语句和索引
优化方案
1.代码优化:
for循环次数过多、做太多无谓的条件判断、相同逻辑重复多次等。比如一个update操作,先查询出entity再执行update,这无疑多了一次数据库交互。
2.定位慢sql,并优化:
用自带的慢查询日志或者开源的慢查询系统定位到具体出问题的sql,然后用explain等工具调优。
3.sqlserver执行计划:
A)通过执行计划可以得到:那些步骤花费的成本比较高。
B)哪些步骤产生的数据量多,数据量的多少用线条的粗细表示,很直观。
C)每一步执行了哪些操作。
4.具体优化手段:
A)少用或者不用sql自带函数,例如
select id from t where substring(name,1,3) = 'abc'
select id from t where datediff(day,createdate,’2005-11-30′) = 0
可以改写为
select id from t where name like 'abc%'
select id from t where createdate >= ‘2005-11-30’ and createdate < ‘2005-12-1’
B)连续数值条件,用between不用in:
select id from t where num between 1 and 5
C)update语句,如果只修改1到2个字段,不要update全字段,否则频繁调用会引起明显的性能消耗
D)尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型。
E)不建议使用select * from , 而是用具体字段名 select id from
F)表与表之间通过一个冗余字段来关联,要比直接使用JOIN有更好的性能
G)select count(*) from table;这样不带任何条件的count会引起全表扫描
5.合理使用索引:
A)索引一般是以空间换时间的一种策略,索引本身在提高查询效率的同时会影响插入、更新、删除的效率。
B)选择合适的索引列,选择在WHERE/GROUP BY/ORDER BY/ON从句中出现的列作为索引项,对于离散度不大的列没有必要创建索引。
索引类型:
主键索引
唯一索引
普通索引(辅助索引、二级索引)
组合索引
全文索引
可以应用索引的操作符:
大于等于
Between
IN
LIKE 不以 % 开头
不能应用索引的操作符:
NOT IN
LIKE %_ 开头
如何选择索引字段
A:字段出现在查询条件中,并且查询条件可以使用索引
B:通常对数字的索引和检索要比对字符串的索引和检索效率更高
C:语句执行频率高,一天会有几千次以上
D:通过字段条件可筛选的记录集很小
6.分表:
A)分表方式:
水平分割(按行)
垂直分割(按列)
B)分表场景:
A: 根据经验,mysql表数据一般达到百万级别,查询效率就会很低。
B: 一张表的某些字段值比较大并且很少使用。可以将这些字段隔离成单独一张表,通过外键关联,例如考试成绩,我们通常关注分数,不关注考试详情。
C)水平分表策略:
按时间分表:当数据有很强的实效性,例如微博的数据,可以按月分割。
按区间分表:例如用户表 1到一百万用一张表,一百万到两百万用一张表。
hash分表:通过一个原始目标id或者是名称按照一定的hash算法计算出数据存储的表名。
7.读写分离:
当一台服务器不能满足需求时,采用读写分离【写: update/delete/add】的方式进行集群。
一台数据库支持最大连接数是有限的,如果用户的并发访问很多,一台服务器无法满足需求,可以集群处理。mysql集群处理技术最常用的就是读写分离。
主从同步:数据库最终会把数据持久化到磁盘,集群必须确保每个数据库服务器的数据是一致的。从库读主库写,从库从主库上同步数据。
读写分离:使用负载均衡实现,写操作都往主库上写,读操作往从服务器上读。
8.缓存:
9.GVM调优:
10.异步/多线程:
针对某些客户端的请求,在服务端可能需要针对这些请求做一些附属的事情,这些事情其实用户并不关心或者用户不需要立即拿到这些事情的处理结果,
这种情况就比较适合用异步的方式处理这些事情。
异步作用
A:缩短接口响应时间,使用户的请求快速返回,用户体验更好。
B:避免线程长时间处于运行状态,这样会引起服务线程池的可用线程长时间不够用,进而引起线程池任务队列长度增大,
从而阻塞更多请求任务,使得更多请求得不到技术处理。
C:线程长时间处于运行状态,可能还会引起系统Load、CPU使用率、机器整体性能下降等一系列问题,甚至引发雪崩。
异步的思路可以在不增加机器数和CPU数的情况下,有效解决这个问题。
异步实现
A:额外开辟线程,这里可以采用额外开辟一个线程或者使用线程池的做法,在IO线程(处理请求响应)之外的线程来处理相应的任务,
在IO线程中让response先返回。
B:使用消息队列(MQ)中间件服务
11.搜索引擎:
例如:solr,elasticsearch