数据库相关的优化

来源:互联网 发布:westlife知乎 编辑:程序博客网 时间:2024/06/01 23:12

优化SQL语句

1. 检查索引

    尽量避免全表扫描,首先应考虑在join , where,order by, group by 等涉及的列上建立索引。

    避免在where字句中使用!=或<>操作符;避免在 where 子句中对字段进行 null 值判断;避免在 where 子句中使用 or 来连接条件,可用 union all 代替 or;避免 like "%abc" ;in 操作可用 join 代替;not exist 代替 not in ;不要在 where 列上进行表达式或函数操作;

2. 在所需要的最小数据集上操作

     当where有多个查新条件时,讲数据结果小的条件放前面;如果是复合索引的话,注意索引的使用顺序;

3. 移除不必要的字段和表

    避免 select * 操作;注意使用 limit;

4. 通过 explain 分析低效 SQL 的执行信息;

5. 定位执行效率低下的SQL语句

    启动慢查询,查看慢查询日志

6. 使用 show processlist查看当前MYSQL的线程

    慢查询日志在查询结束以后才纪录,而 show processlist 命令查看当前 MySQL 在进行的线程,包括线程的状态,是否锁表等等,可以实时的查看 SQL 执行情况, 同时对一些锁表操作进行优化。

优化索引

1. 是否建立合适的索引
    应考虑经常用作搜索条件的地方建立索引。如 join , where,order by, group by 等涉及的列上建立索引
2. 是否过度索引
    如果记录太少,数据的区分度太低,经常增删查的表,不应建立索引。
2. 索引是否失效
    记录太少,对索引所在的列上计算,like “%abc”,
3. 短索引
4. 组合索引
5. 根据慢查询的结果进行优化

优化数据库

1. 根据业务情况调整数据库参数;

2. 优化 sql 语句和索引;

3. 加缓存,memcached,redis;

4. 以上都做了后,还是慢,就做主从复制或主主复制,读写分离,可以在应用层做,效率高;

5. 如果以上都做了还是慢,不要想着去做切分,mysql自带分区表,先试试这个,对你的应用是透明的,无需更改代码,但是sql语句是需要针对分区表做优化的,sql条件中要带上分区条件的列,从而使查询定位到少量的分区上,否则就会扫描全部分区,

6. 如果以上都做了,那就先做垂直拆分,其实就是根据你模块的耦合度,将一个大的系统分为多个小的系统,也就是分布式系统;

7. 才是水平切分,针对数据量大的表,这一步最麻烦,最能考验技术水平,要选择一个合理的sharding key,为了有好的查询效率,表结构也要改动,做一定的冗余,应用也要改,sql中尽量带sharding key,将数据定位到限定的表上去查,而不是扫描全部的表;


MySQL 数据库配置优化

1.  key_buffer_size

作用:指定用于索引的缓冲区大小,增加它可得到更好的索引处理性能。对于内存在4GB左右的服务器该参数可设置为256M或384M。

优化:这对MyISAM表来说非常重要。如果只是使用MyISAM表,可以把它设置为可用内存的 30-40%。合理的值取决于索引大小、数据量以及负载 — 记住,MyISAM表会使用操作系统的缓存来缓存数据,因此需要留出部分内存给它们,很多情况下数据比索引大多了。尽管如此,需要总是检查是否所有的 key_buffer 都被利用了 — .MYI 文件只有 1GB,而 key_buffer 却设置为 4GB 的情况是非常少的。这么做太浪费了。如果你很少使用MyISAM表,那么也保留低于 16-32MB 的 key_buffer_size 以适应给予磁盘的临时表索引所需。

2. max_connections

如果你经常看到‘Too many connections'错误,是因为max_connections的值太低了。这非常常见因为应用程序没有正确的关闭数据库连接,你需要比默认的151连接数更大的值。max_connection值被设高了(例如1000或更高)之后一个主要缺陷是当服务器运行1000个或更高的活动事务时会变的没有响应。在应用程序里使用连接池或者在MySQL里使用进程池有助于解决这一问题。 

3.  innodb_buffer_pool_size

安装完InnoDB后第一个应该设置的选项。缓冲池是数据和索引缓存的地方:这个值越大越好,这能保证你在大多数的读取操作时使用的是内存而不是硬盘。

这对Innodb表来说非常重要。Innodb相比MyISAM表对缓冲更为敏感。MyISAM可以在默认的 key_buffer_size 设置下运行的可以,然而Innodb在默认的 innodb_buffer_pool_size 设置下却跟蜗牛似的。由于Innodb把数据和索引都缓存起来,无需留给操作系统太多的内存,因此如果只需要用Innodb的话则可以设置它高达 70-80% 的可用内存。一些应用于 key_buffer 的规则有 — 如果你的数据量不大,并且不会暴增,那么无需把 innodb_buffer_pool_size 设置的太大了。

4.  innodb_log_file_size

这是redo日志的大小。redo日志被用于确保写操作快速而可靠并且在崩溃时恢复。

在高写入负载尤其是大数据集的情况下很重要。这个值越大则性能相对越高,但是要注意到可能会增加恢复时间。我经常设置为 64-512MB,跟据服务器大小而异。

5.  innodb_log_buffer_size

默认的设置在中等强度写入负载以及较短事务的情况下,服务器性能还可以。如果存在更新操作峰值或者负载较大,就应该考虑加大它的值了。如果它的值设置太高了,可能会浪费内存 — 它每秒都会刷新一次,因此无需设置超过1秒所需的内存空间。通常 8-16MB 就足够了。越小的系统它的值越小。

6.  innodb_flush_logs_at_trx_commit

是否为Innodb比MyISAM慢1000倍而头大?看来也许你忘了修改这个参数了。默认值是 1,这意味着每次提交的更新事务(或者每个事务之外的语句)都会刷新到磁盘中,而这相当耗费资源,尤其是没有电池备用缓存时。很多应用程序,尤其是从 MyISAM转变过来的那些,把它的值设置为 2 就可以了,也就是不把日志刷新到磁盘上,而只刷新到操作系统的缓存上。日志仍然会每秒刷新到磁盘中去,因此通常不会丢失每秒1-2次更新的消耗。如果设置 为 0 就快很多了(设置为0就是等到innodb_log_buffer_size列队满后再统一储存),不过也相对不安全了 — MySQL服务器崩溃时就会丢失一些事务。设置为 2 指挥丢失刷新到操作系统缓存的那部分事务。