数据库的优化有几个层面
1.系统级优化;
2.数据库参数优化;
3.数据库语句优化。
在优化之前,我们先了解下Mysql的体系架构。
概念
在说体系结构之前,先说两个名词,而且是在数据库领域里很常见的两个词:“数据库”和“数据库实例”。
我想,小伙伴们肯定都知道这两个名词的,而且有时候还经常会区分不出来。那么,什么是“数据库”?什么又是“数据库实例”呢?下面我就详细跟大家说说。
首先说“数据库”,数据库是物理操作系统文件或其他形式的文件类型的集合。在 MySQL 中,数据库文件可以是 frm、myd、myi、ibd 结尾的文件。
然后说“数据库实例”,数据库实例是由数据库后台进程/线程以及一个共享内存区组成。共享内存可以被运行的后台进程/线程所共享。需要注意的是,数据库实例才是真正用来操作数据库文件的。
这两个词有时可以互换使用,但两者的概念完全不同。在 MySQL 中,实例和数据库通常关系是一 一对应的,即一个实例对应一个数据库,一个数据库对应一个实例。但是,在集群情况下,可能存在一个数据库可被多个实例使用的情况。
体系结构
MySQL 是一个可移植的数据库,几乎能在当前所有的操作系统上运行,如 Unix/Linux、Windows、Mac 和 Solaris。各种系统在底层实现方面各有不同,但是 MySQL 基本上能保证在各个平台上的物理体系结构的一致性。

MySQL 由以下几部分组成:
-
Connectors:不同语言中与 SQL 的交互
max_connections:就是整个MySQL实例的最大连接数限制
max_user_connections:是单个用户的最大连接数,这里未指明是哪个用户,是任意一个用户。
-
Management Serveices & Utilities:系统管理和控制工具
备份和恢复的安全性,复制,集群,管理,配置,迁移和元数据。
进行身份验证、线程重用,连接限制,检查内存,数据缓存;管理用户的连接,线程处理等需要缓存的需求。
进行 DML、DDL,存储过程、视图、触发器等操作和管理;用户通过 SQL 命令来查询所需结果。
查询翻译对象的特权;SQL 命令传递到解析器的时候会被解析器验证和解析。
在 MySQL 优化语句过程中,可以通过设置 optimize_switch 控制优化行为。在生产环境上,某时间段 MySQL 服务器压力特别大,load 一度达到了 100,查询发现数据库中有大量的 sql 语句 state 状态 result sorting ,result sorting 这种排序特别消耗 cpu 和内存资源。抽取其中的一条 sql 查看执行计划。
全局和引擎特定的缓存和缓冲区;
MySQL 的 Windows 版本默认存储引擎为 InnoDB,InnoDB 支持事务,并且提供行级的锁定。
系统级优化
1)NUMA
在NUMA架构出现前,CPU欢快的朝着频率越来越高的方向发展。受到物理极限的挑战,又转为核数越来越多的方向发展。如果每个core的工作性质都是share-nothing(类似于map-reduce的node节点的作业属性),那么也许就不会有NUMA。由于所有CPU Core都是通过共享一个北桥来读取内存,随着核数如何的发展,北桥在响应时间上的性能瓶颈越来越明显。于是,聪明的硬件设计师们,先到了把内存控制器(原本北桥中读取内存的部分)也做个拆分,平分到了每个die上。于是NUMA就出现了!
非一致存储访问结构 (NUMA : Non-Uniform Memory Access) 也是最新的内存管理技术。它和对称多处理器结构 (SMP : Symmetric Multi-Processor) 是对应的。简单的队别如下:

每个 CPU 都有自己的运行队列,内核会平衡各个内存的运行队列(rebalancing),当0号CPU的运行进程被调度至1号 CPU 的运行队列中,由于进程需要原来的数据,那么1号 CPU 就有可能需要访问0号 CPU 的专用内存(请求0号CPU的内存控制器),此时需要跨越 CPU 插槽,需要多个 CPU 时钟周期。NUMA 架构不适合用于运行数据库服务,由于每个 CPU 使用自身的内存,因此可能出现一个 CPU 的内存使用完,而另一个 CPU 的内存有大量剩余,造成内存资源的浪费,甚至可能出现内存有较多剩余,系统却一直使用
swap 空间的情况。
MySQL在NUMA架构上会出现的问题
- CPU规模因摩尔定律指数级发展,而总线发展缓慢,导致多核CPU通过一条总线共享内存成为瓶颈
- 于是NUMA出现了,CPU平均划分为若干个Chip(不多于4个),每个Chip有自己的内存控制器及内存插槽
- CPU访问自己Chip上所插的内存时速度快,而访问其他CPU所关联的内存(下文称Remote Access)的速度相较慢三倍左右
- 于是Linux内核默认使用CPU亲和的内存分配策略,使内存页尽可能的和调用线程处在同一个Core/Chip中
- 由于内存页没有动态调整策略,使得大部分内存页都集中在CPU
0上
- 又因为Reclaim默认策略优先淘汰/Swap本Chip上的内存,使得大量有用内存被换出
- 当被换出页被访问时问题就以数据库响应时间飙高甚至阻塞的形式出现了
关闭 NUMA
- 从 BIOS 关闭
- 在操作系统中关闭,在 /etc/grub/grub.conf 的 kernel 行追加 numa=off
关于NUMA,有篇不错的文章推荐 http://cenalulu.github.io/linux/numa/
2)malloc
安装jemalloc,进行内存调度,整体来看,jemalloc内存分配方式与glic的malloc内存分配方式相比,提高了MySQL的性能,降低了系统CPU和内存资源的利用。
jemalloc相比于系统的glibc的malloc的优势,以及安装配置,点击连接查看。
http://blog.csdn.net/yumushui/article/details/37758835
https://blog.linuxeye.cn/356.html
3)内存插法
6根内存在4通道里的插法为:2/2/1/1,简称42插法
6根内存在4通道里的插法为:2/2/2/0,简称33插法
HP/DELL/华为/英业达对比:
–HP/DELL/华为保持42插法性能会比33插法性能高。NUMA开启,QPS提升8-20%;NUMA关闭,QPS值能提升12-38%。
–英业达无论何种插法都表现良好
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
数据库参数优化
推荐两篇文章
http://www.ha97.com/4110.html
http://blog.csdn.net/dbanote/article/details/38051255
重要的几个参数:
innodb_buffer_pool_size
innodb_buffer_pool_instances
innodb_log_file_size
innodb_log_buffer_size
innodb_thread_concurrency
innodb_io_capacity
innodb_max_dirty_pages_pct
innodb_flush_method
innodb_file_per_table
innodb_flush_log_at_trx_commit
sync_binlog