性能优化分为四大块:
表结构的优化(含索引)
SQL语句的优化 底层
参数优化
硬件配置优化
一.表结构
为字段选择合适的数据类型(int>char>varchar 快)
表结构的设计,将字段多的表分解成多个表,增加中间表,
混用范式与反范式,适当冗余(可用触发器更新冗余列)
索引:
1.索引的类型:
1.b+索引,参见 《MySQL三部曲--1 数据库为什么要用B+树结构,InnoDB与MyISAM区别》
2.Hash索引
缺点:hash索引并不是按照索引值顺序存储的,所以无法用于排序
只支持等值查找,不能用于范围查找
需要解决hash冲突,如果在低选择性的列上建立hash索引,解决冲突代价很大
3.R-tree
MyISAM支持空间索引, R树是 B树 向 多维空间发展的另一种形式,它将对象空间按范围划分,每个结点都对应一个区域和
一个磁盘页,非叶结点的磁盘页中存储其所有子结点的区域范围,非叶结点的 所有子结点的区域都落在它的区域范围之内;
叶结点的磁盘页中存储其区域范围之内的所有空间对象的外接矩形。R树是一种动态索引结构。(大部分人不使用)
4.全文索引
解决出现这样的问题使“分词”成为全文索引的关键技术。目前有两种基本的方法:
二元法 它把所有有可能的每两两汉字的组合看为一个词组,这样就没有维护词库的开销。
词库法 它使使用词库中的词作为切分的标准,这样也出现了词库跟不上词汇发展的问题,除非你维护词库。
5.其他索引
还有一些存储引擎使用不同类型的索引,如TokuDB使用分形树索引
注:当数据量较少时,大部分情况下简单的全表扫描更高效。对于中大型表,索引非常有效。单对于超大型表,建立和使用
索引的代价将随之增长(维护索引),这时可以直接区分查询需要的一组数据,而不是一条条匹配,
列如
分区表( http://www.cnblogs.com/zemliu/archive/2013/07/21/3203511.html)
二.SQL优化
一 般来说,Query 语句的优化思路和原则主要提现在以下几个方面:
1. 优化更需要优化的 Query:执行次数多的,优化后效率高,多并发时安全性执行多的页容易出问题
2. 定位优化对象的性能瓶颈:IO(数据访问消耗大量时间)还是CPU(数据运算如分组排序等)
3. 明确的优化目标:
4. 从 Explain 入手:根据结果集 type key 等
5. 多使用 profile:根据profile分析CPU/IO
6. 永远用小结果集驱动大的结果集;loop 循环总次数少
7. 尽可能在索引中完成排序:排序 分组 去重等需要排序的方法用索引会快速完成(利用B+树的叶子节点指针)
8. 只取出自己需要的 Columns:取出不必要的列信息可能会增大反应时间
9. 仅仅使用最有效的过滤条件:where 的条件使用不同会使查询的方式不同,如使用不同的索引
10. 尽可能避免复杂的 Join 和子查询:复杂语句分解后,每次锁定的资源减少,阻塞的其他线程也就少了
1.order by 利用索引文件的有序指针直接读取,效率更高
2.group by 是通过先排序,然后分组,如果还有聚合函数则需再进行一个函数的计算,所以也可以利用索引文件
3distinct 是将groupby 每组只去一个结果,所以也可以利用索引文件
1.优化子查询:MySQL需要为内层查询语句的查询结果建立一个临时表。MySQL需要插销这些临时表。所以在MySQL中可以使用连接查询来代替子查询。连接查询不需要建立临时表,其速度比子查询要快。
用join 代替 子查询 如:
2.1 单引号:当数据是int型的时候,where id ='10' 将不会使用索引,索引注意单引号
2.2distinct:可用于去重,(代替group by)select distinct name from student;
2.3order by:默认是由低到高升序(ASC),DESC表示降序(不写默认升序,一个列对应一个升或降)
2.
为查询缓存优化你的查询
像 NOW() 和 RAND() 或是其它的诸如此类的SQL函数都不会开启查询缓存,因为这些函数的返回是会不定的易变的。所以,你所需要的就是用一个变量来代替MySQL的函数,从而开启缓存。
3.当只要一行数据时使用 LIMIT 1
4.在Join表的时候使用相当类型的例,并将其索引,
5.避免 SELECT *
6.永远为每张表设置一个ID,使用 VARCHAR 类型来当主键会使用得性能下降,在MySQL数据引擎下,还有一些操作需要使用主键,在这些情况下,主键的性能和设置变得非常重要,比如,集群,分区……
7. 使用 ENUM 而不是 VARCHAR ,ENUM 类型是非常快和紧凑的。在实际上,其保存的是 TINYINT,但其外表上显示为字符串。这样一来,用这个字段来做一些选项列表变得相当的完美。
8.从 PROCEDURE ANALYSE() 取得建议
PROCEDURE ANALYSE() 会让 MySQL 帮你去分析你的字段和其实际的数据,并会给你一些有用的建议。只有表中有实际的数据,这些建议才会变得有用,因为要做一些大的决定是需要有数据作为基础的。
9. 尽可能的使用 NOT NULL
10.无缓冲的查询
mysql_unbuffered_query() 发送一个SQL语句到MySQL而并不像mysql_query()一样去自动fethch和缓存结果。这会相当节约很多可观的内存,尤其是那些会产生大量结果的查询语句,并且,你不需要等到所有的结果都返回,只需要第一行数据返回的时候,你就可以开始马上开始工作于查询结果了。
11.固定长度的表会更快
char > varchar
12.小心“永久链接”
你只有有限的链接数,内存问题,文件句柄数,等等。
三.底层参数优化
MySQL参数的优化:内存中会为MySQL保留部分的缓冲区。这些缓冲区可以提高MySQL的速度。缓冲区的大小都是在MySQL的配置文件中进行设置的。
下面对几个重要的参数进行详细介绍:
- key_buffer_size:表示索引缓存的大小。这个值越大,使用索引进行查询的速度就越快
- table_cache:表示同时打开的表的个数。这个值越大,能同时打开的表的个数就越多。这个值不是越大越好,因为同时打开的表过多会影响操作系统的性能。
- query_cache_size:表示查询缓冲区的大小。使用查询缓存区可以提高查询的速度。这个方式只使用与修改操作少且经常执行相同的查询操作的情况;默认值是0.
- Query_cache_type:表示查询缓存区的开启状态。0表示关闭,1表示开启。
- Max_connections:表示数据库的最大连接数。这个连接数不是越大越好,因为连接会浪费内存的资源。
- Sort_buffer_size:排序缓存区的大小,这个值越大,排序就越快。
- Innodb_buffer_pool_size:表示InnoDB类型的表和索引的最大缓存。这个值越大,查询的速度就会越快。这个值太大了就会影响操作系统的性能。
四.硬件配置优化
CPU 内存 固态硬盘
架构: