Mysql数据库优化
to be add...
---------------------------------------------------------------------------------------------------------------------
前辈文章原址
http://blog.chinaunix.net/uid-20639775-id-3154234.html
说明:本文的环境为CENTOS 5.5 64 Bit /Mysql 5.1.50
简介:使用Mysql有一段时间了,期间做了不少关于Mysql优化、设计、维护的工作,这两天有时间做一下简单的总结,方便自己回忆,同时也希望能对大家有点帮助.
I 硬件配置优化
- CPU选择:多核的CPU,主频高的CPU
 - 内存:更大的内存
 - 磁盘选择:更快的转速、RAID、阵列卡,
 - 网络环境选择:尽量部署在局域网、SCI、光缆、千兆网、双网线提供冗余、0.0.0.0多端口绑定监听
 
II 操作系统级优化
- 使用64位的操作系统,更好的使用大内存。
 - 设置noatime,nodiratime
 
[zhangxy@dowload_server1 ~]$ cat /etc/fstab
LABEL=/ / ext3 defaults,noatime,nodiratime 1 1
/dev/sda5 /data xfs defaults,noatime,nodiratime 1 2
- 优化内核参数
 
net.ipv4.tcp_keepalive_time=7200
net.ipv4.tcp_max_syn_backlog=1024
net.ipv4.tcp_syncookies=1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.neigh.default.gc_thresh3 = 2048
net.ipv4.neigh.default.gc_thresh2 = 1024
net.ipv4.neigh.default.gc_thresh1 = 256
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.forwarding = 1
net.ipv4.conf.default.proxy_arp = 0
net.ipv4.tcp_syncookies = 1
net.core.netdev_max_backlog = 2048
net.core.dev_weight = 64
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_rfc1337 = 1
net.ipv4.tcp_sack = 0
net.ipv4.tcp_fin_timeout = 20
net.ipv4.tcp_keepalive_probes = 5
net.ipv4.tcp_max_orphans = 32768
net.core.optmem_max = 20480
net.core.rmem_default = 16777216
net.core.rmem_max = 16777216
net.core.wmem_default = 16777216
net.core.wmem_max = 16777216
net.core.somaxconn = 500
net.ipv4.tcp_orphan_retries = 1
net.ipv4.tcp_max_tw_buckets = 18000
net.ipv4.ip_forward = 0
net.ipv4.conf.default.proxy_arp = 0
net.ipv4.conf.all.rp_filter = 1
kernel.sysrq = 1
net.ipv4.conf.default.send_redirects = 1
net.ipv4.conf.all.send_redirects = 0
net.ipv4.ip_local_port_range = 5000 65000
kernel.shmmax = 167108864
vm.swappiness=0
- 加大文件描述符限制
 
Vim /etc/security/limits.conf
加上
* soft nofile 65535
* hard nofile 65535
- 文件系统选择 xfs
 
/dev/sda5 /data xfs defaults,noatime,nodiratime 1 2
III      Mysql设计优化
III.1存储引擎的选择
- Myisam:数据库并发不大,读多写少,而且都能很好的用到索引,sql语句比较简单的应用,TB数据仓库
 - Innodb:并发访问大,写操作比较多,有外键、事务等需求的应用,系统内存较大。
 
III.2命名规则
- 多数开发语言命名规则:比如MyAdress
 - 多数开源思想命名规则:my_address
 - 避免随便命名
 
III.3字段类型选择
字段类型的选择的一般原则:
- 根据需求选择合适的字段类型,在满足需求的情况下字段类型尽可能小。
 - 只分配满足需求的最小字符数,不要太慷慨。
 
原因:更小的字段类型更小的字符数占用更少的内存,占用更少的磁盘空间,占用更少的磁盘IO,以及占用更少的带宽。
III.3.1 整型:
见如下图:
| 
 类型  | 
 字节  | 
 最小值  | 
 最大值  | 
| 
 (带符号的/无符号的)  | 
 (带符号的/无符号的)  | 
||
| 
 TINYINT  | 
 1  | 
 -128  | 
 127  | 
| 
 0  | 
 255  | 
||
| 
 SMALLINT  | 
 2  | 
 -32768  | 
 32767  | 
| 
 0  | 
 65535  | 
||
| 
 MEDIUMINT  | 
 3  | 
 -8388608  | 
 8388607  | 
| 
 0  | 
 16777215  | 
||
| 
 INT  | 
 4  | 
 -2147483648  | 
 2147483647  | 
| 
 0  | 
 4294967295  | 
||
| 
 BIGINT  | 
 8  | 
 -9223372036854775808  | 
 9223372036854775807  | 
| 
 0  | 
 18446744073709551615  | 
根据满足需求的最小整数为选择原则,能用INT的就不要用BIGINT。
用无符号INT存储IP,而非CHAR(15)。
III.3.2 浮点型:
| 
 类型  | 
 字节  | 
 精度类型  | 
 使用场景  | 
| 
 FLOAT(M,D)  | 
 4  | 
 单精度  | 
 精度要求不高,数值比较小  | 
| 
 DOUBLE(M,D)(REAL)  | 
 8  | 
 双精度  | 
 精度要求不高,数值比较大  | 
| 
 DECIMAL(M,D)(NUMERIC)  | 
 M+2  | 
 自定义精度  | 
 精度要求很高的场景  | 
III.3.3 时间类型
| 
 类型  | 
 取值范围  | 
 存储空间  | 
 零值表示法  | 
| 
 DATE  | 
 1000-01-01~9999-12-31  | 
 3字节  | 
 0000-00-00  | 
| 
 TIME  | 
 -838:59:59~838:59:59  | 
 3字节  | 
 00:00:00  | 
| 
 DATETIME  | 
 1000-01-01 00:00:00~9999-12-31 23:59:59  | 
 8字节  | 
 0000-00-00 00:00:00  | 
| 
 TIMESTAMP  | 
 19700101000000~2037年的某个时刻  | 
 4字节  | 
 00000000000000  | 
| 
 YEAR  | 
 YEAR(4):1901~2155 YEAR(2):1970~2069  | 
 1字节  | 
 0000  | 
III.3.4 字符类型
| 
 类型  | 
 最大长度  | 
 占用存储空间  | 
| 
 CHAR[(M)]  | 
 M字节  | 
 M字节  | 
| 
 VARCHAR[(M)]  | 
 M字节  | 
 M+1字节  | 
| 
 TINYBLOD,TINYTEXT  | 
 2^8-1字节  | 
 L+1字节  | 
| 
 BLOB,TEXT  | 
 2^16-1字节  | 
 L+2  | 
| 
 MEDIUMBLOB,MEDIUMTEXT  | 
 2^24-1字节  | 
 L+3  | 
| 
 LONGBLOB,LONGTEXT  | 
 2^32-1字节  | 
 L+4  | 
| 
 ENUM('value1','value2',...)  | 
 65535个成员  | 
 1或2字节  | 
| 
 SET('value1','value2',...)  | 
 64个成员  | 
 1,2,3,4或8字节  | 
注:L表示可变长度的意思
对于varchar和char的选择要根据引擎和具体情况的不同来选择,主要依据如下原则:
- 如果列数据项的大小一致或者相差不大,则使用char。
 - 如果列数据项的大小差异相当大,则使用varchar。
 - 对于MyISAM表,尽量使用Char,对于那些经常需要修改而容易形成碎片的myisam和isam数据表就更是如此,它的缺点就是占用磁盘空间。
 - 对于InnoDB表,因为它的数据行内部存储格式对固定长度的数据行和可变长度的数据行不加区分(所有数据行共用一个表头部分,这个标头部分存放着指向各有关数据列的指针),所以使用char类型不见得会比使用varchar类型好。事实上,因为char类型通常要比varchar类型占用更多的空 间,所以从减少空间占用量和减少磁盘i/o的角度,使用varchar类型反而更有利。
 - 表中只要存在一个varchar类型的字段,那么所有的char字段都会自动变成varchar类型,因此建议定长和变长的数据分开。
 
III.4编码选择
单字节 latin1
多字节 utf8(汉字占3个字节,英文字母占用一个字节)
如果含有中文字符的话最好都统一采用utf8类型,避免乱码的情况发生。
III.5主键选择原则
注:这里说的主键设计主要是针对INNODB引擎
- 能唯一的表示行。
 - 显式的定义一个数值类型自增字段的主键,这个字段可以仅用于做主键,不做其他用途。
 - MySQL主键应该是单列的,以便提高连接和筛选操作的效率。
 - 主键字段类型尽可能小,能用SMALLINT就不用INT,能用INT就不用BIGINT。
 - 尽量保证不对主键字段进行更新修改,防止主键字段发生变化,引发数据存储碎片,降低IO性能。
 - MySQL主键不应包含动态变化的数据,如时间戳、创建时间列、修改时间列等。
 - MySQL主键应当有计算机自动生成。
 - 主键字段放在数据表的第一顺序。
 
推荐采用数值类型做主键并采用auto_increment属性让其自动增长。
III.6其他需要注意的地方
- NULL OR NOT NULL
 
尽可能设置每个字段为NOT NULL,除非有特殊的需求,原因如下:
- 使用含有NULL列做索引的话会占用更多的磁盘空间,因为索引NULL列需要而外的空间来保存。
 - 进行比较的时候,程序会更复杂。
 - 含有NULL的列比较特殊,SQL难优化,如果是一个组合索引,那么这个NULL 类型的字段会极大影响整个索引的效率。
 
- 索引
 
索引的缺点:极大地加速了查询,减少扫描和锁定的数据行数。
索引的缺点:占用磁盘空间,减慢了数据更新速度,增加了磁盘IO。
添加索引有如下原则:
- 选择唯一性索引。
 - 为经常需要排序、分组和联合操作的字段建立索引。
 - 为常作为查询条件的字段建立索引。
 - 限制索引的数据,索引不是越多越好。
 - 尽量使用数据量少的索引,对于大字段可以考虑前缀索引。
 - 删除不再使用或者很少使用的索引。
 - 结合核心SQL优先考虑覆盖索引。
 - 忌用字符串做主键。
 
- 反范式设计
 
适当的使用冗余的反范式设计,以空间换时间有的时候会很高效。
IV Mysql软件优化
- 开启mysql复制,实现读写分离、负载均衡,将读的负载分摊到多个从服务器上,提高服务器的处理能力。
 - 使用推荐的GA版本,提升性能
 - 利用分区新功能进行大数据的数据拆分
 
V Mysql配置优化
注意:全局参数一经设置,随服务器启动预占用资源。
- key_buffer_size参数
 
mysql索引缓冲,如果是采用myisam的话要重点设置这个参数,根据(key_reads/key_read_requests)判断
- innodb_buffer_pool_size参数
 
INNODB 数据、索引、日志缓冲最重要的引擎参数,根据(hit riatos和FILE I/O)判断
- wait_time_out参数
 
线程连接的超时时间,尽量不要设置很大,推荐10s
- max_connections参数
 
服务器允许的最大连接数,尽量不要设置太大,因为设置太大的话容易导致内存溢出,需要通过如下公式来确定:
SET @k_bytes = 1024;
SET @m_bytes = @k_bytes * 1024;
SET @g_bytes = @m_bytes * 1024;
SELECT
(
@@key_buffer_size + @@query_cache_size + @@tmp_table_size+
@@innodb_buffer_pool_size + @@innodb_additional_mem_pool_size+
@@innodb_log_buffer_size+
@@max_connections *
( @@read_buffer_size + @@read_rnd_buffer_size + @@sort_buffer_size+
@@join_buffer_size + @@binlog_cache_size + @@thread_stack
) )
/ @g_bytes AS MAX_MEMORY_USED_GB;
- thread_concurrency参数
 
线程并发利用数量,(cpu+disk)*2,根据(os中显示的请求队列和tickets)判断
- sort_buffer_size参数
 
获得更快的--ORDER BY,GROUP BY,SELECT DISTINCT,UNION DISTINCT
- read_rnd_buffer_size参数
 
当根据键进行分类操作时获得更快的--ORDER BY
- join_buffer_size参数
 
join连接使用全表扫描连接的缓冲大小,根据select_full_join判断
- read_buffer_size参数
 
全表扫描时为查询预留的缓冲大小,根据select_scan判断
- tmp_table_size参数
 
临时内存表的设置,如果超过设置就会转化成磁盘表,根据参数(created_tmp_disk_tables)判断
- innodb_log_file_size参数(默认5M)
 
记录INNODB引擎的redo log文件,设置较大的值意味着较长的恢复时间。
- innodb_flush_method参数(默认fdatasync)
 
Linux系统可以使用O_DIRECT处理数据文件,避免OS级别的cache,O_DIRECT模式提高数据文件和日志文件的IO提交性能
- innodb_flush_log_at_trx_commit(默认1)
 
- 0表示每秒进行一次log写入cache,并flush log到磁盘。
 - 1表示在每次事务提交后执行log写入cache,并flush log到磁盘。
 - 2表示在每次事务提交后,执行log数据写入到cache,每秒执行一次flush log到磁盘。
 
VI Mysql语句级优化
- 性能查的读语句,在innodb中统计行数,建议另外弄一张统计表,采用myisam,定期做统计.一般的对统计的数据不会要求太精准的情况下适用。
 - 尽量不要在数据库中做运算。
 - 避免负向查询和%前缀模糊查询。
 - 不在索引列做运算或者使用函数。
 - 不要在生产环境程序中使用select * from 的形式查询数据。只查询需要使用的列。
 - 查询尽可能使用limit减少返回的行数,减少数据传输时间和带宽浪费。
 - where子句尽可能对查询列使用函数,因为对查询列使用函数用不到索引。
 - 避免隐式类型转换,例如字符型一定要用’’,数字型一定不要使用’’。
 - 所有的SQL关键词用大写,养成良好的习惯,避免SQL语句重复编译造成系统资源的浪费。
 - 联表查询的时候,记得把小结果集放在前面,遵循小结果集驱动大结果集的原则。
 - 开启慢查询,定期用explain优化慢查询中的SQL语句。
 
Mysql数据库优化的更多相关文章
- 关于MySQL数据库优化的部分整理
		
在之前我写过一篇关于这个方面的文章 <[原创]为什么使用数据索引能提高效率?(本文针对mysql进行概述)(更新)> 这次,主要侧重点讲下两种常用存储引擎. 我们一般从两个方面进行MySQ ...
 - 【MySQL】花10分钟阅读下MySQL数据库优化总结
		
1.花10分钟阅读下MySQL数据库优化总结http://www.kuqin.com2.扩展阅读:数据库三范式http://www.cnblogs.com3.my.ini--->C:\Progr ...
 - 30多条mysql数据库优化方法,千万级数据库记录查询轻松解决(转载)
		
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...
 - 50多条mysql数据库优化建议
		
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 缺省情况下建立的索引是非群集索引,但有时它并不是最佳的.在非群集索引下,数据在物理上随机存 ...
 - 解开发者之痛:中国移动MySQL数据库优化最佳实践(转)
		
开源数据库MySQL比较容易碰到性能瓶颈,为此经常需要对MySQL数据库进行优化,而MySQL数据库优化需要运维DBA与相关开发共同参与,其中MySQL参数及服务器配置优化主要由运维DBA完成,开发则 ...
 - 30多条mysql数据库优化方法【转】
		
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...
 - 百万行mysql数据库优化和10G大文件上传方案
		
百万行mysql数据库优化和10G大文件上传方案 最近这几天正在忙这个优化的方案,一直没时间耍,忙碌了一段时间终于还是拿下了这个项目?项目中不要每次都把程序上的问题,让mysql数据库来承担,它只是个 ...
 - 从运维角度来分析mysql数据库优化的一些关键点【转】
		
概述 一个成熟的数据库架构并不是一开始设计就具备高可用.高伸缩等特性的,它是随着用户量的增加,基础架构才逐渐完善. 1.数据库表设计 项目立项后,开发部根据产品部需求开发项目,开发工程师工作其中一部分 ...
 - 关于mysql数据库优化
		
关于mysql数据库优化 以我之愚见,数据库的优化在于优化存储和查询速度 目前主要的优化我认为是优化查询速度,查询速度快了,提高了用户的体验 我认为优化主要从两方面进行考虑, 优化数据库对象, 优化s ...
 - mysql数据库优化 pt-query-digest使用
		
mysql数据库优化 pt-query-digest使用 一.pt-query-digest工具简介 pt-query-digest是用于分析 mysql慢查询的一个工具,它可以分析binlog.Ge ...
 
随机推荐
- scrollIntoView
			
DOM的滚动 DOM规范中并没有规定各浏览器需要实现怎样的滚动页面区域,各浏览器实现了相应的方法,可以使用不同的方式控制页面区域的滚动.这些方法作为HTMLElement类型的扩展存在,所以它能在所有 ...
 - BZOJ4454: C Language Practice
			
Description Input 第一行输入一个正整数T(T<=85),表示测试数据的组数. 每组数据第一行包含两个正整数n,m(1<=n,m<=2000),表示序列的长度. 第二 ...
 - Crystal Reports 2008(水晶报表) 第一个报表
			
学习Craystal Reports 2008的时候,光看说明文档,很多东西看了就忘了. 我在看文档的时候,是跟着文档上面来做的. 这样边看边做,效果还不错哈 下面就是我的第一个demo 先看看效果: ...
 - java enum(枚举)使用详解 + 总结
			
enum 的全称为 enumeration, 是 JDK 1.5 中引入的新特性,存放在 java.lang 包中. 下面是我在使用 enum 过程中的一些经验和总结,主要包括如下内容: 1. 原始 ...
 - Enumerators and Enumerable
			
Next week task is to learn how generic enumeration interface works, try to build a sample and write ...
 - 【java】[转]标记接口和标记注解注解
			
Java中的标记接口和标记注解 http://blog.sina.com.cn/s/blog_7fdce91f0101d93m.html
 - [LintCode] Integer to Roman 整数转化成罗马数字
			
Given an integer, convert it to a roman numeral. The number is guaranteed to be within the range fro ...
 - [LintCode] Paint House II 粉刷房子之二
			
There are a row of n houses, each house can be painted with one of the k colors. The cost of paintin ...
 - Point Grey articles link
			
Point Grey areaDetector driver Bumblebee XB3 Specifications FlyCapture SDK Example Source Code Under ...
 - android-Spinner的学习和使用
			
Spinner下拉列表的使用和功能 执行步骤: * 1.添加一个下拉列表项的list * 2.为下拉列表定义一个数组适配器(ArrayAdapter),添加数据资源 * 3.位适配器设置下拉列表下拉时 ...