[关闭]
@jingwentian 2015-02-23T10:06:38.000000Z 字数 5011 阅读 1554

性能优化之MySQL优化

视频:www.imooc.com 文字:get.jobdeer.com

SQL语句优化

1. MySQL慢查日志的开启方式和存储格式

2. MySQL慢查日志分析工具之mysqldumpslow

3. MySQL慢查日志分析工具之pt-query-digest

4. 如何通过慢查日志发现有问题的SQL

  1. 查询次数多且每次查询占用时间长的SQL

    通常为pt-query-digest分析的前几个查询
    
  2. IO大的SQL

    注意pt-query-digest分析的Rows examine项
    
  3. 未命中索引的SQL

    注意pt-query-digest分析的Rows examine(扫描行数) 和 Rows Send(发送行数)的对比
    

5. 通过explain查询和分析SQL的执行计划

explain返回各项的含义:

6. Count()和Max()的优化

7. 子查询的优化

通常情况下,需要把子查询优化为join查询,但在优化时需要注意关联键是否有一对多的关系,要注意重复数据。

8. group by的优化

9. Limit查询的优化

limit常用与分页处理,时常会伴随着order by 从句使用,因此大多时候会使用filesorts,这样会造成大量的IO问题

    SELECT film_id,description FROM sakila.film ORDER BY title LIMIT 50,5

索引优化

1. 如何选择合适的列建立索引

2. 索引优化SQL的方法

  1. 索引的维护及优化 - 重复及冗余索引

重复索引是只相同的列以相同的顺序简历同类型的索引,如下表中primary keyID列上的索引就是重复索引

    CREATE table test(
        id init not null primary key,
        name varchar(10) not null,
        title varchar(50) not null,
        unique(id)
    )engine=innodb;
  1. 索引的维护及优化 - 查找重复及冗余索引

    SELECT a.TABLE_SCHEMA AS '数据库名'
        ,a.table_name as '表名'
        ,a.index_name AS '索引1'
        ,b.INDEX_NAME AS '索引2'
        ,a.COLUMN_NAME AS '重复列名' 
    FROM STATISTICS a JOIN STATISTICS b 
    ON a.TABLE_SCHEMA=b.TABLE_SCHEMA AND 
       a.TABLE_NAME=b.TABLE_NAME AND 
       a.SEQ_IN_INDEX=b.SEQ_IN_INDEX AND 
       a.COLUMN_NAME=b.COLUMN_NAME 
    WHERE a.SEQ_IN_INDEX = 1 AND a.INDEX_NAME <> b.INDEX_NAME;
    
    1. 索引的维护及优化 - 查找重复及冗余索引工具

    使用pt-duplicate-key-checker工具检查重复及冗余索引

    pt-duplicate-key-checker \
    -uroot \
    -p '123456'  \
    -h 127.0.0.1
    

3. 索引维护的方法

索引的维护及优化 - 删除不用的索引

pt-index-usage \
-uroot \
-p 'tjw199022' \
-h 127.0.0.1 \
/usr/local/mysql/var/localhost-slow.log

3. 数据库结构优化

1. 选择合适的数据类型

数据类型的选择,重点在于 合适 二字,如何确定选择的数据类型是否合适?

例1

使用int来存储日期时间,利用FROM_UNIXTIME(),UNIX_TIMESTAMP()两个函数来进行转换

CREATE TABLE test(
    id INT AUTO_INCREMENT NOT NULL,
    timestr INT,
    PRIMARY KEY(id)
);

INSERT INTO test(timestr) VALUES(UNIX_TIMESTAMP('2014-06-01 13:12:00'));

SELECT FROM_UNIXTIME(timestr) FROM test;

例2

使用bigint来存储IP地址,利用INET_ATON(),INET_NTOA()两个函数来进行转换

CREATE TABLE sessions(
    id INT AUTO_INCREMENT NOT NULL,
    ipaddress BIGINT,
    PRIMARY KEY(id)
); 

INSERT INTO sessions(ipaddress) VALUES(INET_ATON(192.168.0.1));

SELECT INET_NTOA(ipaddress) FROM sessions;

2. 表的范式化优化

3. 表的反范式化优化

4. 表的垂直拆分(解决宽度问题)

所谓垂直拆分,就是把原来一个有很多列的表拆分成多个表,这解决了表的宽度问题。通常垂直拆分可以按以下原则进行:

5. 表的水平拆分 (解决数据量问题)

表的水平拆分是为了解决单表的数据量过大的问题,水平拆分的表每一个表的结构都是完全一致的。

常用的水平拆分方法为:

  1. customer_id进行hash运算,如果要拆分成5个表则使用mod(customer_id,5)取出0-4个值(对5取模)
  2. 针对不同的hashID把数据存到不同的表中

挑战:

  1. 跨分区表进行数据查询
  2. 统计及后台报表操作

4. 系统配置优化

1. 数据库系统配置优化

网络方面的配置,要修改/etc/sysctl.conf

    #增加tcp支持的队列数
    net.ipv4.tcp_max_syn_backlog = 65535
    #减少断开连接时,资源回收
    net.ipv4.tcp_max_tw_buckets = 8000
    net.ipv4.tcp_tw_reuse = 1
    net.ipv4.tcp_tw_recycle = 1
    net.ipv4.tcp_fin_timeout = 10

打开文件数的限制,可以使用ulimit -a查看目录的各位限制,可以修改/etc/security/limits.conf文件,增加以下内容以修改打开文件数量的限制

    soft nofile 65535
    hard nofile 65535

2. MySQL配置文件优化

    innodb_buffer_pool-size:非常重要的一个参数,用于配置Innodb的缓冲池,如果数据库中个只有Innodb表,则推荐配置量为总内存的75%.

    innodb_buffer_pool_instances:Mysql5.5中新增加参数,可以控制缓冲池的个数,默认情况下只有一个缓冲池

    Innodb_log_buffer_size:innodb log 缓冲的大小,由于日志最长每秒钟就会刷新所以一般不用太大

    innodb_flush_log_at_trx_commit:关键参数,对innodb的IO效率影响很大。默认值为1,可以取0,1,2三个值,一般建议设为2,但如果数据安全性要求比较高则使用默认值1.

    innodb_read_io_threads,innodb_write_io_threads:决定了Innodb读写的IO进程数,默认为4

    innodb_file_per_table:关键参数,控制Innodb每一个表使用独立的表空间,默认为off,也就是所有表都会建立在共享表空间中

    innodb_stats_on_metadata:决定了Mysql在什么情况下会刷新innodb表的统计信息

3. 第三方工具 Percon Configuration Wizard

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注