Mysql性能优化详解

Posted Blue92120

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mysql性能优化详解相关的知识,希望对你有一定的参考价值。

1.为什么要进行sql优化

  因为没有进行sql优化的语句执行性能低下。而性能低下的原因:sql语句欠佳,索引失效,服务器参数设置不合理(缓冲、线程数)

  本文整个优化过程 主要是围绕索引进行

  2.mysql安装启动配置(CentOS7)

  1)版本介绍与选择

  目前主流版本 5.x

  5.0-5.1: 相当于4.x版本的延续,升级维护

  5.4 -5.x: Mysql整合了三方公司的新存储引擎 (推荐使用5.7版本,当前比较稳定的版本)

  2)mysql安装-rpm

  2.1检查服务器msyql安装情况,有就先卸载自带的mysql【Centos7 默认安装mariadb】

  > rpm -qa|grep 软件名字 【检查命令】

  >

  > rpm -e --nodeps 软件包名 【卸载命令】

  >

  > yum remove 软件包名 【卸载命令】

  rpm -qa|grep mariadb

  //卸载方式一

  rpm -e --nodeps mariadb-libs-5.5.44-2.el7.centos.x86_64

  //卸载方式二(建议使用yum卸载,可自动处理依赖关系)

  yum remove mariadb-libs-5.5.44-2.el7.centos.x86_64

  2.2下载安装包

  https://downloads.mysql.com/archives/community/

 

  2.3解压安装包到/usr/local/mysql

mkdir /usr/local/mysql
tar -xvf mysql-5.7.25-1.el7.x86_64.rpm-bundle.tar -C /usr/local/mysql

  

2.4按照顺序安装rpm安装包

#先安装依赖
yum install net-tools

#注意: 下列安装包的安装顺序不能变rpm -ivh mysql-community-common-5.7.25-1.el7.x86_64.rpm
rpm -ivh mysql-community-libs-5.7.25-1.el7.x86_64.rpm
rpm -ivh mysql-community-devel-5.7.25-1.el7.x86_64.rpm
rpm -ivh mysql-community-libs-compat-5.7.25-1.el7.x86_64.rpm
rpm -ivh mysql-community-client-5.7.25-1.el7.x86_64.rpm
rpm -ivh mysql-community-server-5.7.25-1.el7.x86_64.rpm

  

2.5验证是否安装成功【查看mysql版本】

mysqladmin --version

  

2.6mysql常用命令

  systemctl status mysqld 查看mysql服务状态

  systemctl start mysqld 启动mysql服务

  systemctl stop mysqld 停止mysql服务

  systemctl enable mysqld 设置开机时启动mysql服务,避免每次开机启动mysql

  2.7设置密码

/usr/bin/mysqladmin -u root password 'new-password'

  

2.8登录

mysql -u root -p

  

2.9设置root用户远程连接权限和密码

mysql> grant all privileges on  *.*  to  'root'  @'%'  identified  by  'remote-password';
mysql> flush  privileges;

  

2.10开放端口

firewall-cmd --zone=public --add-port=3306/tcp --permanent
firewall-cmd --reload

  

3.逻辑分层,存储引擎,解析过程

  1)逻辑分层

  连接层 - 提供与客户端连接的服务

  服务层 - 1.提供各种用户使用的接口(增删改查,等) 2.提供sql优化器(mysql query optimizer)

  引擎层 - 提供了各种存储数据的方式(InnoDB,MyISAM)

  存储层 - 存储数据

  2)存储引擎

  2.1常用引擎(InnoDB, MyISAM)

  MyISAM:ISAM是Indexed Sequential Access Method (有索引的顺序访问方法) 的缩写,它是存储记录和文件的标准方法。不是事务安全的,而且不支持外键,如果执行大量的select,insert MyISAM比较适合

  InnoDB:支持事务安全的引擎,支持外键、行锁、事务是他的最大特点。如果有大量的update和insert,建议使用InnoDB,特别是针对多个并发和QPS较高的情况

  2.2区别

1.MyISAM不支持事务,而InnoDB支持。InnoDB的AUTOCOMMIT默认是打开的,即每条SQL语句会默认被封装成一个事务,自动提交,这样会影响速度,所以最好是把多条SQL语句显示放在begin和commit之间,组成一个事务去提交。

  2. MyISAM只支持表级锁,用户在操作myisam表时,select,update,delete,insert语句都会给表自动加锁,如果加锁以后的表满足insert并发的情况下,可以在表的尾部插入新的数据。

  InnoDB:支持行级锁和事务,是innodb的最大特色。行锁大幅度提高了多用户并发操作的新能。但是InnoDB的行锁,只是在有索引时是有效的,无索引或索引失效都会锁全表的。

  3. InnoDB支持外键,MyISAM不支持。

  4. InnoDB的主键范围更大,最大是MyISAM的2倍。

  5. InnoDB不支持全文索引,而MyISAM支持。全文索引是指对char、varchar和text中的每个词(停用词除外)建立倒排序索引。MyISAM的全文索引其实没啥用,因为它不支持中文分词,必须由使用者分词后加入空格再写到数据表里,而且少于4个汉字的词会和停用词一样被忽略掉。

  6. MyISAM支持GIS数据,InnoDB不支持。即MyISAM支持以下空间数据对象:Point,Line,Polygon,Surface等。

  7. 没有where的count(*)使用MyISAM要比InnoDB快得多。因为MyISAM内置了一个计数器,count(*)时它直接从计数器中读,而InnoDB必须扫描全表。所以在InnoDB上执行count(*)时一般要伴随where,且where中要包含主键以外的索引列。为什么这里特别强调“主键以外”?因为InnoDB中primary index是和raw data存放在一起的,而secondary index则是单独存放,然后有个指针指向primary key。所以只是count(*)的话使用secondary index扫描更快,而primary key则主要在扫描索引同时要返回raw data时的作用较大。

  2.3存储结构

  InnoDB 和 Myisam 都是用 B+Tree 来存储数据的。

  一般情况3层B+Tree可以存放上百万条数据

  3)解析过程

  3.1sql编写过程:

select dinstinct..from..join..on..where..groupby..having..orderby..limit..

  3.2sql解析过程:

from..on..join..where..groupby..having..select dinstinct..orderby..limit..

  4.索引

  1)什么是索引

  索引: 相当于书的目录,是帮助mysql高效获取数据的数据结构

  2)索引类型

  普通索引: index 命名: idx_字段名

  唯一索引: unique 命名: uk_字段名

  主键索引: primary key 命名: pk_字段名

  复合索引: 多个字段组成的索引(name,age) 命名: 按索引顺序字段名命名 idx_name_age

  复合索引并不一定所有索引字段都会用到。当name已经查询出结果是,不会再去查询age索引

  但为了性能考虑建议在sql语句中用到所有的索引字段

  3)创建索引

方式一: create    索引类型   索引名 on  表(字段);
方式二: altertable 表名 addconstraint  索引名   索引类型(字段);
//简单索引
mysql>createindex idx_dept on tb(dept);//唯一索引
mysql>createuniqueindex uk_name on tb(name);//复合索引
mysql>createindex idx_dept_name on tb(dept,name);//主键索引
mysql>altertable tb addconstraint pk_id primarykey(id);

  

4)删除索引

  > drop index 索引名 on 表名;

mysql>dropindex uk_name on tb;
mysql>dropindex idx_dept on tb;
mysql>dropindex idx_dept_name on tb;

  

5)查询索引

  > show index from 表名;

mysql>showindexfrom tb;

  

6)不适合创建索引的字段

  索引本身需要的存储空间很大的字段

  频繁需要修改的字段

  很少使用的列 (sql语句中用不到的列)

  重复值多的列

  5.执行计划

  1)数据准备

mysql>createtable tab_school_timetable(stid int(3),stname varchar(20),tid int(3));
mysql>createtable tab_teacher(tid int(3),tname varchar(20));
mysql>createtable tab_teacher_card(tcid int(3), tid int(3),tcdesc varchar(200));
mysql>createtable tab_school_timetable(stid int(3),stname varchar(20),tid int(3));
mysql>createtable tab_teacher(tid int(3),tname varchar(20));
mysql>createtable tab_teacher_card(tcid int(3), tid int(3),tcdesc varchar(200));

  2)语法

  > explain sql语句;

  3)explain信息详解 id

  > id:sql语句执行的编号

  >

  > id值相同,从上往下顺序执行。这个顺序受表数据量的大小影响,先查数据量小的,后查数据量大的

  >

  > id值不同:先执行id值大的

#查询课程编号为2 或 教师证编号为3 的老师信息explainselect t.tname from tab_teacher t, tab_school_timetable st, tab_teacher_card tc where t.tid = st.tid  and t.tid = tc.tcid and(st.stid =2or tc.tcid =3);

 

#查询教授sql课程老师的描述信息explainselect tc.tcdesc from tab_teacher_card tc where tc.tid =(select st.tid from tab_school_timetable st where st.stname ='sql')

  

  4)explain信息详解 select_type

  select_type 查询类型

  PRIMARY: 主查询,sql中包含有子查询

  SUBQUERY: 子查询

  SIMPLE: 普通查询 (不含有子查询和union 连接查询的查询)

  DERIVED: 衍生查询 (使用到了临时表)

  union: 使用到了union 连接查询

  union result: 显示拿些表之间使用了union

  5)explain信息详解 table

  表名

  6)explain信息详解 type

  > type 索引类型

  >

  > 常用到的类型system > const > eq_ref > ref > range > index > all

  >

  > system 性能最高,all性能最低。 实际项目中达到 ref > range 性能就行

  >

  > system : 表只有中一条数据的主查询

  >

  > const : 查询结果只有一条数据的sql ,并且索引类型必须为主键索引或者唯一索引

  >

  > eq_ref : 查询结果可以有多条数据,但满足where判断条件的每一条数据必须是唯一的一条数据(不能多条也不能为0条)。

explainselect t.tname from teacher t,teacherCard tc where t.tid = tc.tid;``` 
ref :   索引查询返回匹配所有行(0条,多条)
explainselect t.tname from tab_teacher t where t.tname ='ta';

range  : 检索指定范围的行,where后面是一个范围查询(between,in,>,<  等   其中in可能会导致索引失效而变成 all)
explainselect tc.tcdesc from tab_teacher_card tc where tc.tid between1and2;```index :  查询全部索引的数据
explainselect t.tid from tab_teacher t;```all :查询全部表的数据(sql 将表的所有数据都查了一遍) ,没有用到索引时常出现
explainselect st.stname from tab_school_timetable st;

  7)explain信息详解 possible_keys

  可供选择的索引

  8)explain信息详解key

  实际用到的索引

  9)explain信息详解key_len

  实际使用到索引的长度(utf8 1个字符3个字节)

  10)explain信息详解ref

  表之间的引用-指明当前表所参照的字段

  const: 判断条件中用到了常量 或者 显示用到了其他表的那些字段

  11)explain信息详解rows

  估计查询了表中的数据行数(MySQL认为必须检查以执行查询的行数)

  12)explain信息详解extra

  > 准备工作

createtable t (
    a1 char(3),
    a2 char(3),
    a3 char(3),index idx_a1(a1),index idx_a2(a2),index idx_a3(a3));

  

> using filesort : 性能损耗大,需要额外的查询(排序) ,常见于 order by 语句中

#当排序和查找不是同一个字段就会出现using filesortexplainselect t.a1,t.a2,t.a3 from t where t.a1 =''orderby a2;//反例explainselect t.a1,t.a2,t.a3 from t where t.a1 =''orderby a1;//正例#复合索引不能跨列(最佳左前缀)否则会出现using filesortcreateindex idx_a1_a2_a3 on t(a1,a2,a3);explainselect t.a1,t.a2,t.a3 from t where t.a1 =''orderby a3;//反例(跨了 a2)explainselect t.a1,t.a2,t.a3 from t where t.a2 =''orderby a3;//反例(跨了 a1)explainselect t.a1,t.a2,t.a3 from t where t.a1 =''orderby a2;//正例

> using temporary:性能损耗大,用到了临时表,一般出现与 group by 语句中

explainselect t.a1,t.a2,t.a3 from t where a1 in('1','2','3')groupby a2;//反例explainselect t.a1,t.a2,t.a3 from t where a1 in('1','2','3')groupby a1;//正例

  

> using index: 性能提升,只从索引中查询数据,不需要回表查询

>

> using where: 进行了回表查询

dropindex idx_a1_a2_a3 on t;createindex idx_a1_a2 on t(a1,a2);explainselect a1,a2 from t where a1=''and a2 ='';//正例explainselect a1,a3 from t where a1='';//反例

 

  

> impossible where : where 查询条件永远为fasle

explainselect a1 from t where a1='a'and a1 ='b';

> Using join buffer : MySQL引擎使用了连接缓存,表示sql语句太烂,性能低下

  6.慢查询

  1)慢查询有什么用

  开启慢查询后,可以根据日志信息分析那些SQL语句性能低下,从而针对性的进行优化

  2)检查是否开启了慢查询

mysql>show variables like'%slow_query_log%';

  3)开启慢查询

#临时开启 - mysql重启后失效
mysql>setglobal slow_query_log =1;
#永久开启 -  修改my.cnf 文件vim /etc/my.cnf
[mysqld]
slow_query_log =1
slow_query_log_file =/var/lib/mysql/localhost-slow.log

  4)慢查询阈值

#查看
mysql>show variables like'%long_query_time%';#临时设置(单位秒) - 重新登陆起效
mysql>setglobal long_query_time =2;
#永久设置 - 修改my.cnf 文件vim /etc/my.cnf
[mysqld]
long_query_time =2

  

5)查看超过慢查询阈值的sql次数

mysql>showglobalstatuslike'%slow_queries%';

  

6)查看超过慢查询阈值具体的sql信息

  > 1.查看slow_query_log_file日志文件

  >

  > 2.使用mysqldumpslow工具

mysqldumpslow --help-s : 排序方式  (r 逆序)-l :锁定时间
-t :查询多少条
-g : 正则表达式

//获取返回记录最多的3个SQL
mysqldumpslow -s r -t 3/var/lib/mysql/localhost-slow.log

//获取访问次数最多的3个SQL
mysqldumpslow -s c -t 3/var/lib/mysql/localhost-slow.log

//按照时间排序,查询前10条包含left join查询语句的sql
mysqldumpslow -s t -t 10-g 'left join'/var/lib/mysql/localhost-slow.log

  

7.优化总结

  ```ABAP

  优化一般不能一次就优化到最佳效果,需要在开发过程中根据使用情况多次逐步优化

  ```

  > 1. 复合索引保证最佳左前缀原则

  >

  > 2. 小表驱动大表

  >

  > 3. 索引建立在经常查询的字段上

  >

  > 4. 复合索引,尽量使用全索引匹配(说明:假设使用了三个字段建立了一个复合索引,在sql查询中尽量让三个索引都用到)

  >

  > 5. 不要在索引上进行任何操作(计算、函数、类型转换),否则索引失效

  >

  > 6. 复合索引不能使用不等于( != , <> )和 is null, is not null ,否则索引失效

  >

  > 7. like 尽量以 ‘常量’ 开头,不要使用 ‘%x%’ ,否则索引失效

  >

  > 8. 尽量不要使用or ,否则索引失效

  >

  > 9. 如果必须使用到索引失效的情况,尽量使用索引覆盖(using index),可能会使索引生效,达到性能优化

  >

  > 10. 将含有in的范围查询放到where条件的最后面,防止索引失效(尽量不使用in)

  >

  > 11. 连接查询 a.t = b.t 的情况下,将表数据量小的放在左边,表数据量大的放在右边会提高性能

  >

  > 12. 连接查询 a.t = b.t 的情况下,将 a 表 t 字段加索引会提高性能

  >

  > 13. 对于左外连接给左表加索引,右外连接给右表加索引

  >

  > 14. exist 和 in,如果主查询的数据集大,则使用in,如果子查询的数据集大,使用exist

  >

  > 15. 提高 order by 查询的策略

  >

  > a、选择使用单路、双路;调整buffer的容量大小

  > b、避免使用 select * ...

  > c、保证排序字段的 排序一致性

mysql服务性能优化—my.cnf配置说明详解

MYSQL服务器my.cnf配置文档详解
硬件:内存16G

 

[client]
port = 3306
socket = /data/3306/mysql.sock

[mysql]
no-auto-rehash

[mysqld]
user = mysql
port = 3306
socket = /data/3306/mysql.sock
basedir = /usr/local/mysql
datadir = /data/3306/data
open_files_limit = 10240

back_log = 600    #在MYSQL暂时停止响应新请求之前,短时间内的多少个请求可以被存在堆栈中。如果系统在短时间内有很多连接,则需要增大该参数的值,该参数值指定到来的TCP/IP连接的监听队列的大小。默认值50。
max_connections = 3000   #MySQL允许最大的进程连接数,如果经常出现Too Many Connections的错误提示,则需要增大此值。
max_connect_errors = 6000   #设置每个主机的连接请求异常中断的最大次数,当超过该次数,MYSQL服务器将禁止host的连接请求,直到mysql服务器重启或通过flush hosts命令清空此host的相关信息。
复制代码
table_cache = 614   #指示表调整缓冲区大小。# table_cache 参数设置表高速缓存的数目。每个连接进来,都会至少打开一个表缓存。#因此, table_cache 的大小应与 max_connections 的设置有关。例如,对于 200 个#并行运行的连接,应该让表的缓存至少有 200 × N             #,这里 N 是应用可以执行的查询#的一个联接中表的最大数量。此外,还需要为临时表和文件保留一些额外的文件描述符。# 当 Mysql 访问一个表时,如果该表在缓存中已经被打开,则可以直接访问缓存;如果#还没有被缓存,但是在 Mysql 表缓冲区中还有             #空间,那么这个表就被打开并放入表缓#冲区;如果表缓存满了,则会按照一定的规则将当前未用的表释放,或者临时扩大表缓存来存放,使用表缓存的好处是可以更快速地访问表中的内容。执行 flush tables 会#清空缓存的内容。一般来说,可以通过查看数             #据库运行峰值时间的状态值 Open_tables #和 Opened_tables ,判断是否需要增加 table_cache 的值(其中 open_tables 是当#前打开的表的数量, Opened_tables 则是已经打开的表的数量)。即如果open_tables接近table_cache的时候,并             #且Opened_tables这个值在逐步增加,那就要考虑增加这个#值的大小了。还有就是Table_locks_waited比较高的时候,也需要增加table_cache。
复制代码
external-locking = FALSE   #使用–skip-external-locking MySQL选项以避免外部锁定。该选项默认开启
max_allowed_packet = 32M   #设置在网络传输中一次消息传输量的最大值。系统默认值 为1MB,最大值是1GB,必须设置1024的倍数。
sort_buffer_size = 2M   # Sort_Buffer_Size 是一个connection级参数,在每个connection(session)第一次需要使用这个buffer的时候,一次性分配设置的内存。
               #Sort_Buffer_Size 并不是越大越好,由于是connection级的参数,过大的设置+高并发可能会耗尽系统内存资源。例如:500个连接将会消耗 500*sort_buffer_size(8M)=4G内存
               #Sort_Buffer_Size 超过2KB的时候,就会使用mmap() 而不是 malloc() 来进行内存分配,导致效率降低。
join_buffer_size = 2M   #用于表间关联缓存的大小,和sort_buffer_size一样,该参数对应的分配内存也是每个连接独享。
thread_cache_size = 300     # 服务器线程缓存这个值表示可以重新利用保存在缓存中线程的数量,当断开连接时如果缓存中还有空间,那么客户端的线程将被放到缓存中,如果线程重新被请求,那么请求将从缓存中读取,如果缓存中是空的或者是新的请求,那么这个线程将被重新创建                  #,如果有很多新的线程,增加这个值可以改善系统性能.通过比较 Connections 和 Threads_created 状态的变量,可以看到这个变量的作用。设置规则如下:1GB 内存配置为8,2GB配置为16,3GB配置为32,4GB或更高内存,可配置更大。
thread_concurrency = 8   # 设置thread_concurrency的值的正确与否, 对mysql的性能影响很大, 在多个cpu(或多核)的情况下,错误设置了thread_concurrency的值, 会导致mysql不能充分利用多cpu(或多核), 出现同一时刻只能一个cpu(或核)在工作的情况。thread_co               #ncurrency应设为CPU核数的2倍. 比如有一个双核的CPU, 那么thread_concurrency的应该为4; 2个双核的cpu, thread_concurrency的值应为8
复制代码
query_cache_size = 64M    # 对于使用MySQL的用户,对于这个变量大家一定不会陌生。前几年的MyISAM引擎优化中,这个参数也是一个重要的优化参数。但随着发展,这个参数也爆露出来一些问题。机器的内存越来越大,人们也都习惯性的把以前有用的参数分配的值越来越大。这个                #参数加大后也引发了一系列问题。我们首先分析一下 query_cache_size的工作原理:一个SELECT查询在DB中工作后,DB会把该语句缓存下来,当同样的一个SQL再次来到DB里调用时,DB在该表没发生变化的情况下把结果从缓存中返回给Client。这                 #里有一个关建点,就是DB在利用Query_cache工作时,要求该语句涉及的表在这段时间内没有发生变更。那如果该表在发生变更时,Query_cache里的数据又怎么处理呢?首先要把Query_cache和该表相关的语句全部置为失效,然后在写入更新。那么                 #如果Query_cache非常大,该表的查询结构又比较多,查询语句失效也慢,一个更新或是Insert就会很慢,这样看到的就是Update或是Insert怎么这么慢了。所以在数据库写入量或是更新量也比较大的系统,该参数不适合分配过大。而且在高并发,写入                #量大的系统,建议把该功能禁掉。
复制代码
query_cache_limit = 4M   #指定单个查询能够使用的缓冲区大小,缺省为1M
复制代码
query_cache_min_res_unit = 2k    #默认是4KB,设置值大对大数据查询有好处,但如果你的查询都是小数据查询,就容易造成内存碎片和浪费
                    #查询缓存碎片率 = Qcache_free_blocks / Qcache_total_blocks * 100%
                    #如果查询缓存碎片率超过20%,可以用FLUSH QUERY CACHE整理缓存碎片,或者试试减小query_cache_min_res_unit,如果你的查询都是小数据量的话。
                    #查询缓存利用率 = (query_cache_size – Qcache_free_memory) / query_cache_size * 100%
                    #查询缓存利用率在25%以下的话说明query_cache_size设置的过大,可适当减小;查询缓存利用率在80%以上而且Qcache_lowmem_prunes > 50的话说明query_cache_size可能有点小,要不就是碎片太多。
                    #查询缓存命中率 = (Qcache_hits – Qcache_inserts) / Qcache_hits * 100%
复制代码
default-storage-engine = MyISAM
 #default_table_type = InnoDB
thread_stack = 192K   #设置MYSQL每个线程的堆栈大小,默认值足够大,可满足普通操作。可设置范围为128K至4GB,默认为192KB
transaction_isolation = READ-COMMITTED   ## 设定默认的事务隔离级别.可用的级别如下:
                         # 1.READ UNCOMMITTED-读未提交2.READ COMMITTE-读已提交3.REPEATABLE READ -可重复读4.SERIALIZABLE -串行
tmp_table_size = 256M     # tmp_table_size 的默认大小是 32M。如果一张临时表超出该大小,MySQL产生一个 The table tbl_name is full 形式的错误,如果你做很多高级 GROUP BY 查询,增加 tmp_table_size 值。如果超过该值,则会将临时表写入磁盘。
复制代码
max_heap_table_size = 256M
 long_query_time = 2
 log_long_format
 log-slow-queries=/data/3306/slow-log.log
 #log-bin = /data/3306/mysql-bin
 log-bin
 binlog_cache_size = 4M
 max_binlog_cache_size = 8M
 max_binlog_size = 512M
 
expire_logs_days = 7  #binlog过期时间自动清理
 
复制代码
key_buffer_size = 2048M   #批定用于索引的缓冲区大小,增加它可以得到更好的索引处理性能,对于内存在4GB左右的服务器来说,该参数可设置为256MB或384MB。
read_buffer_size = 1M   # MySql读入缓冲区大小。对表进行顺序扫描的请求将分配一个读入缓冲区,MySql会为它分配一段内存缓冲区。read_buffer_size变量控制这一缓冲区的大小。如果对表的顺序扫描请求非常频繁,并且你认为频繁扫描进行得太慢,可以通过增加该变量值以               #及内存缓冲区大小提高其性能。和sort_buffer_size一样,该参数对应的分配内存也是每个连接独享。
read_rnd_buffer_size = 16M   # MySql的随机读(查询操作)缓冲区大小。当按任意顺序读取行时(例如,按照排序顺序),将分配一个随机读缓存区。进行排序查询时,MySql会首先扫描一遍该缓冲,以避免磁盘搜索,提高查询速度,如果需要排序大量数据,可适当调高该值。但My                  #Sql会为每个客户连接发放该缓冲空间,所以应尽量适当设置该值,以避免内存开销过大。
bulk_insert_buffer_size = 64M   #批量插入数据缓存大小,可以有效提高插入效率,默认为8M
myisam_sort_buffer_size = 128M   # MyISAM表发生变化时重新排序所需的缓冲
myisam_max_sort_file_size = 10G   # MySQL重建索引时所允许的最大临时文件的大小 (当 REPAIR, ALTER TABLE 或者 LOAD DATA INFILE).
                     # 如果文件大小比此值更大,索引会通过键值缓冲创建(更慢)
myisam_max_extra_sort_file_size = 10G
 
myisam_repair_threads = 1   # 如果一个表拥有超过一个索引, MyISAM 可以通过并行排序使用超过一个线程去修复他们.
                  # 这对于拥有多个CPU以及大量内存情况的用户,是一个很好的选择.
myisam_recover   #自动检查和修复没有适当关闭的 MyISAM 表
skip-name-resolve
lower_case_table_names = 1
 
server-id = 1
innodb_additional_mem_pool_size = 16M   #这个参数用来设置 InnoDB 存储的数据目录信息和其它内部数据结构的内存池大小,类似于Oracle的library cache。这不是一个强制参数,可以被突破。
innodb_buffer_pool_size = 2048M   #这对Innodb表来说非常重要。Innodb相比MyISAM表对缓冲更为敏感。MyISAM可以在默认的 key_buffer_size 设置下运行的可以,然而Innodb在默认的 innodb_buffer_pool_size 设置下却跟蜗牛似的。由于Innodb把数据和索引都缓                     #存起来,无需留给操作系统太多的内存,因此如果只需要用Innodb的话则可以设置它高达 70-80% 的可用内存。一些应用于 key_buffer 的规则有 — 如果你的数据量不大,并且不会暴增,那么无需把 innodb_buffer_pool_size 设置的                     #太大了
innodb_data_file_path = ibdata1:1024M:autoextend   #表空间文件 重要数据
innodb_file_io_threads = 4   #文件IO的线程数,一般为 4,但是在 Windows 下,可以设置得较大。
innodb_thread_concurrency = 8   #服务器有几个CPU就设置为几,建议用默认设置,一般为8.
innodb_flush_log_at_trx_commit = 2   # 如果将此参数设置为1,将在每次提交事务后将日志写入磁盘。为提供性能,可以设置为0或2,但要承担在发生故障时丢失数据的风险。设置为0表示事务日志写入日志文件,而日志文件每秒刷新到磁盘一次。设置为2表示事务日志将在提交时                       #写入日志,但日志文件每次刷新到磁盘一次
innodb_log_buffer_size = 16M     #此参数确定些日志文件所用的内存大小,以M为单位。缓冲区更大能提高性能,但意外的故障将会丢失数据.MySQL开发人员建议设置为1-8M之间
innodb_log_file_size = 128M     #此参数确定数据日志文件的大小,以M为单位,更大的设置可以提高性能,但也会增加恢复故障数据库所需的时间
innodb_log_files_in_group = 3   #为提高性能,MySQL可以以循环方式将日志文件写到多个文件。推荐设置为3M
复制代码
innodb_max_dirty_pages_pct = 90   #推荐阅读 http://www.taobaodba.com/html/221_innodb_max_dirty_pages_pct_checkpoint.html
                     # Buffer_Pool中Dirty_Page所占的数量,直接影响InnoDB的关闭时间。参数innodb_max_dirty_pages_pct 可以直接控制了Dirty_Page在Buffer_Pool中所占的比率,而且幸运的是innodb_max_dirty_pages_pct是可以动态改变的                     #。所以,在关闭InnoDB之前先将innodb_max_dirty_pages_pct调小,强制数据块Flush一段时间,则能够大大缩短 MySQL关闭的时间。
复制代码
innodb_lock_wait_timeout = 120   # InnoDB 有其内置的死锁检测机制,能导致未完成的事务回滚。但是,如果结合InnoDB使用MyISAM的lock tables 语句或第三方事务引擎,则InnoDB无法识别死锁。为消除这种可能性,可以将innodb_lock_wait_timeout设置为一个整数值                    #,指示 MySQL在允许其他事务修改那些最终受事务回滚的数据之前要等待多长时间(秒数)
innodb_file_per_table = 0     #独享表空间(关闭)
复制代码
[mysqldump]
 quick
 max_allowed_packet = 32M
 
[mysqld_safe]
 log-error=/data/3306/mysql_oldboy.err
 pid-file=/data/3306/mysqld.pid
复制代码
复制代码
补充:
 #wait_timeout = 10 
 #指定一个请求的最大连接时间,对于4GB左右的内存服务器来说,可以将其设置为5-10。
 #skip_networking 
 #开启该选可以彻底关闭MYSQL的TCP/IP连接方式,如果WEB服务器是以远程连接的方式访问MYSQL数据库服务器的,则不要开启该选项,否则将无法正常连接。
 
 #log-queries-not-using-indexes
 将没有使用索引的查询也记录下来
复制代码

以上是关于Mysql性能优化详解的主要内容,如果未能解决你的问题,请参考以下文章

MySQL批量SQL插入性能优化详解

mysql GROUP BY、DISTINCT、ORDER BY语句优化

使用Order By NULL 解决 group by后自动排序,优化Sql性能

优化 SQL:如何重写此查询以提高性能? (使用子查询,摆脱 GROUP BY?)

MySQL之SQL优化详解

性能提升1400+倍,快来看MySQL Volcano模型迭代器的谓词位置优化详解