转载自:http://blog.eood.cn/mysql#rd?sukey=fc78a68049a14bb29c60f21c5254b15a1a9234459cf25ff467de14129ca1193806f26d2b87fb50dec98292d5996d09a7

MYSQL 应该是最流行了 WEB 后端数据库。WEB 开发语言最近发展很快,PHP, Ruby, Python, Java 各有特点,虽然 NOSQL 最近越來越多的被提到,但是相信大部分架构师还是会选择 MYSQL 来做数据存储。

MYSQL 如此方便和稳定,以至于我们在开发 WEB 程序的时候很少想到它。即使想到优化也是程序级别的,比如,不要写过于消耗资源的 SQL 语句。但是除此之外,在整个系统上仍然有很多可以优化的地方。

1. 选择合适的存储引擎: INNODB

除非你的数据表使用来做只读或者全文检索 (相信现在提到全文检索,没人会用 MYSQL 了),你应该默认选择 INNODB 。

你自己在测试的时候可能会发现 MYISAM 比 INNODB 速度快,这是因为: MYISAM 只缓存索引,而 INNODB 缓存数据和索引,MYISAM 不支持事务。但是 如果你使用 innodb_flush_log_at_trx_commit = 2可以获得接近的读取性能 (相差百倍) 。

1.1 如何将现有的 MYISAM 数据库转换为 INNODB:

mysql -u [USER_NAME] -p -e "SHOW TABLES IN [DATABASE_NAME];" | tail -n +2 | xargs -I '{}' echo "ALTER TABLE {} ENGINE=INNODB;" > alter_table.sql

perl -p -i -e 's/(search_[a-z_]+ ENGINE=)INNODB/\1MYISAM/g' alter_table.sql

mysql -u [USER_NAME] -p [DATABASE_NAME] < alter_table.sql

1.2 为每个表分别创建 INNODB FILE:

innodb_file_per_table=1

这样可以保证 ibdata1 文件不会过大,失去控制。尤其是在执行 mysqlcheck -o –all-databases 的时候。

2. 保证从内存中读取数据,讲数据保存在内存中

2.1 足够大的 innodb_buffer_pool_size

推荐将数据完全保存在 innodb_buffer_pool_size ,即按存储量规划 innodb_buffer_pool_size 的容量。这样你可以完全从内存中读取数据,最大限度减少磁盘操作。

2.1.1 如何确定 innodb_buffer_pool_size 足够大,数据是从内存读取而不是硬盘?

方法 1

mysql> SHOW GLOBAL STATUS LIKE 'innodb_buffer_pool_pages_%';

+----------------------------------+--------+

| Variable_name | Value |

+----------------------------------+--------+

| Innodb_buffer_pool_pages_data | 129037 |

| Innodb_buffer_pool_pages_dirty | 362 |

| Innodb_buffer_pool_pages_flushed | 9998 |

| Innodb_buffer_pool_pages_free | 0 | !!!!!!!!

| Innodb_buffer_pool_pages_misc | 2035 |

| Innodb_buffer_pool_pages_total | 131072 |

+----------------------------------+--------+

6 rows in set (0.00 sec)

发现 Innodb_buffer_pool_pages_free 为 0,则说明 buffer pool 已经被用光,需要增大 innodb_buffer_pool_size

INNODB 的其他几个参数

innodb_additional_mem_pool_size = 1/200 of buffer_pool

innodb_max_dirty_pages_pct 80%

方法 2

或者用 iostat -d -x -k 1 命令,查看硬盘的操作。

2.1.2 服务器上是否有足够内存用来规划

执行 echo 1 > /proc/sys/vm/drop_caches 清除操作系统的文件缓存,可以看到真正的内存使用量。

2.2 数据预热

默认情况,只有某条数据被读取一次,才会缓存在 innodb_buffer_pool。所以,数据库刚刚启动,需要进行数据预热,将磁盘上的所有数据缓存到内存中。数据预热可以提高读取速度。

对于 InnoDB 数据库,可以用以下方法,进行数据预热:

1. 将以下脚本保存为 MakeSelectQueriesToLoad.sql

SELECT DISTINCT

CONCAT('SELECT ',ndxcollist,' FROM ',db,'.',tb,

' ORDER BY ',ndxcollist,';') SelectQueryToLoadCache

FROM

(

SELECT

engine,table_schema db,table_name tb,

index_name,GROUP_CONCAT(column_name ORDER BY seq_in_index) ndxcollist

FROM

(

SELECT

B.engine,A.table_schema,A.table_name,

A.index_name,A.column_name,A.seq_in_index

FROM

information_schema.statistics A INNER JOIN

(

SELECT engine,table_schema,table_name

FROM information_schema.tables WHERE

engine='InnoDB'

) B USING (table_schema,table_name)

WHERE B.table_schema NOT IN ('information_schema','mysql')

ORDER BY table_schema,table_name,index_name,seq_in_index

) A

GROUP BY table_schema,table_name,index_name

) AA

ORDER BY db,tb

;

2. 执行

mysql -uroot -AN < /root/MakeSelectQueriesToLoad.sql > /root/SelectQueriesToLoad.sql

3. 每次重启数据库,或者整库备份前需要预热的时候执行:

mysql -uroot < /root/SelectQueriesToLoad.sql > /dev/null 2>&1

2.3 不要让数据存到 SWAP 中

如果是专用 MYSQL 服务器,可以禁用 SWAP,如果是共享服务器,确定 innodb_buffer_pool_size 足够大。或者使用固定的内存空间做缓存,使用 memlock 指令。

3. 定期优化重建数据库

mysqlcheck -o –all-databases 会让 ibdata1 不断增大,真正的优化只有重建数据表结构:

CREATE TABLE mydb.mytablenew LIKE mydb.mytable;

INSERT INTO mydb.mytablenew SELECT * FROM mydb.mytable;

ALTER TABLE mydb.mytable RENAME mydb.mytablezap;

ALTER TABLE mydb.mytablenew RENAME mydb.mytable;

DROP TABLE mydb.mytablezap;

4. 减少磁盘写入操作

4.1 使用足够大的写入缓存

innodb_log_file_size

但是需要注意如果用 1G 的 innodb_log_file_size ,假如服务器当机,需要 10 分钟来恢复。

推荐 innodb_log_file_size = 0.25 innodb_buffer_pool_size

4.2 innodb_flush_log_at_trx_commit

这个选项和写磁盘操作密切相关:

innodb_flush_log_at_trx_commit = 1 则每次修改写入磁盘

innodb_flush_log_at_trx_commit = 0/2 每秒写入磁盘

如果你的应用不涉及很高的安全性 (金融系统),或者基础架构足够安全,或者 事务都很小,都可以用

0 或者 2 来降低磁盘操作。

4.3 避免双写入缓冲

innodb_flush_method=O_DIRECT

5. 提高磁盘读写速度

RAID0 尤其是在使用 EC2 这种虚拟磁盘 (EBS) 的时候,使用软 RAID0 非常重要。

6. 充分使用索引

6.1 查看现有表结构和索引

SHOW CREATE TABLE db1.tb1\G

6.2 添加必要的索引

索引是提高查询速度的唯一方法,比如搜索引擎用的倒排索引是一样的原理。

索引的添加需要根据查询来确定,比如通过慢查询日志或者查询日志,或者通过 EXPLAIN 命令分析查询。

ADD UNIQUE INDEX

ADD INDEX

6.2.1 比如,优化用户验证表:

添加索引

ALTER TABLE users ADD UNIQUE INDEX username_ndx (username);

ALTER TABLE users ADD UNIQUE INDEX username_password_ndx (username,password);

每次重启服务器进行数据预热

echo “select username,password from users;” > /var/lib/mysql/upcache.sql

添加启动脚本到 my.cnf

[mysqld]

init-file=/var/lib/mysql/upcache.sql

6.2.2 使用自动加索引的框架或者自动拆分表结构的框架

比如,Rails 这样的框架,会自动添加索引,Drupal 这样的框架会自动拆分表结构。会在你开发的初期指明正确的方向。所以,经验不太丰富的人一开始就追求从 0 开始构建,实际是不好的做法。

7. 分析查询日志和慢查询日志

记录所有查询,这在用 ORM 系统或者生成查询语句的系统很有用。

log=/var/log/mysql.log

注意不要在生产环境用,否则会占满你的磁盘空间。

记录执行时间超过 1 秒的查询

long_query_time=1

log-slow-queries=/var/log/mysql/log-slow-queries.log

8. 激进的方法,使用内存磁盘

现在基础设施的可靠性已经非常高了,比如 EC2 几乎不用担心服务器硬件当机。而且内存实在是便宜,很容易买到几十G内存的服务器,可以用内存磁盘,定期备份到磁盘。

将 MYSQL 目录迁移到 4G 的内存磁盘

mkdir -p /mnt/ramdisk

sudo mount -t tmpfs -o size=4000M tmpfs /mnt/ramdisk/

mv /var/lib/mysql /mnt/ramdisk/mysql

ln -s /tmp/ramdisk/mysql /var/lib/mysql

chown mysql:mysql mysql

9. 用 NOSQL 的方式使用 MYSQL

B-TREE 仍然是最高效的索引之一,所有 MYSQL 仍然不会过时。

用 HandlerSocket 跳过 MYSQL 的 SQL 解析层,MYSQL 就真正变成了 NOSQL。

10. 其他

单条查询最后增加 LIMIT 1,停止全表扫描。

将非”索引”数据分离,比如将大篇文章分离存储,不影响其他自动查询。

不用 MYSQL 内置的函数,因为内置函数不会建立查询缓存。

PHP 的建立连接速度非常快,所有可以不用连接池,否则可能会造成超过连接数。当然不用连接池 PHP 程序也可能将

连接数占满比如用了 @ignore_user_abort(TRUE);

使用 IP 而不是域名做数据库路径,避免 DNS 解析问题

11. 结束

你会发现优化后,数据库的性能提高几倍到几百倍。所以 MYSQL 基本还是可以适用大部分场景的应用的。优化现有系统的成本比系统重构或者迁移到 NOSQL 低很多。

mysql 必读_MYSQL 调优和使用必读相关推荐

  1. 定期存款单的mysql编写程序_MySQL 调优和使用必读

    MYSQL 应该是最流行了 WEB 后端数据库.WEB 开发语言最近发展很快,PHP, Ruby, Python, Java 各有特点,虽然 NOSQL 最近越來越多的被提到,但是相信大部分架构师还是 ...

  2. linux mysql io压力大_MySQL 调优基础(四) Linux 磁盘IO_MySQL

    1. IO处理过程 磁盘IO经常会成为系统的一个瓶颈,特别是对于运行数据库的系统而言.数据从磁盘读取到内存,在到CPU缓存和寄存器,然后进行处理,最后写回磁盘,中间要经过很多的过程,下图是一个以wri ...

  3. linux mysql数据库优化_MySQL_Linux下MySQL数据库性能调优方法,以下的环境具备一定的代表性 - phpStudy...

    Linux下MySQL数据库性能调优方法 以下的环境具备一定的代表性,可以说是中小企业一般配置和工作环境.希望通过本文能让大家理解Linux下MySQL数据库性能调优方法. 硬件准备环境: 硬盘: 1 ...

  4. MySQL 数据库规范--调优篇(终结篇)

    前言 这篇是MySQL 数据库规范的最后一篇--调优篇,旨在提供我们发现系统性能变弱.MySQL系统参数调优,SQL脚本出现问题的精准定位与调优方法. 目录 1.MySQL 调优金字塔理论 2.MyS ...

  5. MySQL多线程并发调优

    学习MySQL数据库技术,一个非常重要的技能就是性能调优.通常情况下,都是自下而上的调优方法,主要包括运行环境.配置参数.SQL性能和系统架构设计调优等. 本文从多线程并发的角度进行的思考,简单描述M ...

  6. MySql查询优化性能调优,sql性能自测方法,及Mysql索引介绍

    MySql查询优化性能调优,sql性能自测方法,及Mysql索引介绍 前言 一.普通优化加索引(适用于where条件后一个查询条件) 二.组合查询加索引(适用于where条件后多个查询条件) 三.My ...

  7. 视频教程-15天入门MySQL和高性能调优视频教程-MySQL

    15天入门MySQL和高性能调优视频教程 负责过多个软件项目的研发.设计和管理工作,拥有项目管理师认证.项目监理师中级认证.出版过的图书有<微信小程序开发图解案例教程><Axure ...

  8. Mysql数据库性能调优面试大全经典分析

    1.为啥要死磕Mysql Mysql作为一款大众免费开源的关系型数据库软件,受到国内很多"穷屌丝"企业的热烈欢迎,看一下目前最新数据库排行,Mysql排在第二位,仅此于Oracle ...

  9. MySQL优化调优有没有做过_MySQL 调优/优化的 100 个建议

    MySQL是一个强大的开源数据库.随着MySQL上的应用越来越多,MySQL逐渐遇到了瓶颈.这里提供 101 条优化 MySQL 的建议.有些技巧适合特定的安装环境,但是思路是相通的.我已经将它们分成 ...

最新文章

  1. JavaWeb总结(六)
  2. python计算圆面积保留两位数_python中怎么实现保留两位小数
  3. IDEA主题设置与eclipse代码风格一致
  4. PHP递归删除目录及目录下的文件
  5. Django中views笔记
  6. 什么是产品的愿景—从一篇博文中学得到
  7. Struts2框架的概念及使用方法
  8. Linux 无线网卡驱动安装 Dell Inspiron R14-N4010 笔记本
  9. DM9000有线网卡驱动编写
  10. word图片与文字居中对齐
  11. 双基因突变患者_一例 Kallmann 综合征患者双基因突变分析
  12. PHP 阿里云实人认证
  13. pythonl list 的修改元素
  14. Linux_03_文档内容相关命令
  15. vscode远程连接服务器失败的问题
  16. 查询Apple app的bundle ID
  17. 2019年年终个人总结
  18. git reset中hard与soft区别
  19. 【它山之玉】Trump:让人们发出噢、啊的惊叹声!—科学网马臻
  20. 华为云平台零代码搭建物联网可视化大屏体验:疫情防控数据大屏

热门文章

  1. 透明大页相关内核参数_Linux7.4 关闭透明大页
  2. 抖音python广告_抖音上好看的小姐姐,Python给你都下载了
  3. Linux系统用户和用户组介绍
  4. VTK:二次曲面用法实战
  5. VTK:vtkAssembly用法实战
  6. OpenCASCADE可视化:3D演示之3D术语表
  7. wxWidgets:wxPixelData< Image, PixelFormat >类模板用法
  8. boost::graph模块使用write_graphviz 输出 BGL adjacency_list 的简单示例
  9. GDCM:gdcm::Parser的测试程序
  10. GDCM:处理(各种操作处理)DICOM图像文件的测试程序