- 使用 status信息对mysql进行具体的优化。
- mysql> show global status //可以列出服务器运行的各种状态值
- mysql> show variables; 查询服务器配置信息
- 执行时间超过2秒即为慢查询 mysql> show variables like ‘slow%’;
- 慢查询时间设置不宜过长,最好5秒之内
- 如果mysql是主-从结构,可以考虑打开其中一台从服务器的慢查询日志,这样既可以监控慢查询,对系统性能影响又小。
- too many connections;
- 增加从服务器分散读压力
- 配置文件中max_connections值过小; mysql> show variables like ‘max_connection’
- 服务器响应的最大连接数; mysql> show global status like ‘max_used_connections’
- 比较理想设置:最大连接数占上限连接数85%左右
- key_buffer_size 对myisam表性能影响最大; mysql> show variables like ‘key_buffer_size’
- key_buffer_size 使用情况 mysql> show global status like ‘key_read%’;
mysql> show global status like ‘key_read%’;
+————————+————-+
| variable_name | value |
+————————+————-+
| key_read_requests | 27813678764 |
| key_reads | 6798830 |
+————————+————-+一共有27813678764个索引读取请求,有6798830个请求在内存中没有找到直接从硬盘读取索引,计算索引未命中缓存的概率:
key_cache_miss_rate = key_reads / key_read_requests * 100%
比如上面的数据,key_cache_miss_rate为0.0244%,4000个索引读取请求才有一个直接读硬盘,已经很bt 了,key_cache_miss_rate在0.1%以下都很好(每1000个请求有一个直接读硬盘),如果key_cache_miss_rate在 0.01%以下的话,key_buffer_size分配的过多,可以适当减少。
* 缓存簇
- 开启查询缓存,某些查询语句会让mysql不适用缓存, 用一个变量来代替MySQL函数,从而开启缓存
提高数据库查询效率
- 尽量避免权标扫描,首先应考虑在
where
及order by
涉及的列上简历索引 - 尽量避免在where子句中对字段进行
NULL
值判断,否则引擎会放弃使用索引而进行权标扫描 - 避免在where子句中使用
!=
或<>
,否则引擎会放弃使用索引而进行权标扫描 - 避免在where子句中使用
or
来连接条件,否则引擎会放弃使用索引而进行权标扫描 in
和not in
也要慎用,对于连续的数值,能用between就不要用in- where语句中使用参数也会导致全表扫描
- 避免在where子句中对字段进行表达式操作
- 避免在where子句中对字段进行函数操作
- 不要在where子句中的
=
左边进行函数,算数运算或其他表达式运算 - 很多时候exists代替in是一个好的选择
- 索引可以提高select效率,但同时也降低了insert和update效率,一个表的索引最好不要超过6个
- 尽量使用数字型字段
- 尽可能使用varchar,nvarchar代替cahr,nchar
- 尽量使用表变量来代替临时表
- 避免频繁创建和删除临时表,
- 创建临时表是如果一次插入数据量大,应使用select into 代替create table避免早场大量log
- 应尽量避免使用游标,效率太差
- 排序尽量使用升序
or
尽量使用union
代替- 删除表中所有记录使用
truncate
不要用delete
- 避免大失误SQL
常用工具:
* mysqldumpslow
* mysql profile
* mysql explain
索引:
* 主键索引
* 唯一索引
* 普通索引
* 全文索引
分表
mysql中有一种机制是表锁定和行锁定,为什么要出现这种机制,是为了保证数据的完整性,我举个例子来说吧,如果有二个sql都要修改同一张表的同一条数据,这个时候怎么办呢,是不是二个sql都可以同时修改这条数据呢?很显然mysql对这种情况的处理是,一种是表锁定(myisam存储引擎),一个是行锁定(innodb存储引擎)。表锁定表示你们都不能对这张表进行操作,必须等我对表操作完才行。行锁定也一样,别的sql必须等我对这条数据操作完了,才能对这条数据进行操作。如果数据太多,一次执行的时间太长,等待的时间就越长,这也是我们为什么要分表的原因。
linux mysql proxy 的安装,配置,以及读写分离
mysql replication 互为主从的安装及配置,以及数据同步
利用merge存储引擎来实现分表
索引
索引的实现通常使用B树及其变种B+树。
优点:
* 加快检索速度
* 加速表和表间的连接
* 减少查询中分组和排序的时间
* 使用优化隐藏器提高系统性能
缺点:
* 创建和维护消耗时间
* 占用物理空间
* 表修改时,索引也要变动
对于那些定义为text, image和bit数据类型的列不应该增加索引
对于那些只有很少数据值的列也不应该增加索引。
对于那些在查询中很少使用或者参考的列不应该创建索引。
在聚集索引中,表中行的物理顺序与键值的逻辑(索引)顺序相同。一个表只能包含一个聚集索引。
局部性原理,磁盘预读
根据b树定义,可知检索一次最多需要访问h个节点。将一个节点的大小设为等于一个页,这样每个节点只需要一次I/O就可以完全载入。
B-Tree中一次检索最多需要h-1次I/O(根节点常驻内存),渐进复杂度为O(h)=O(logdN)。
而红黑树这种结构,h明显要深的多。由于逻辑上很近的节点(父子)物理上可能很远,无法利用局部性,所以红黑树的I/O渐进复杂度也为O(h),效率明显比B-Tree差很多。