Optimzing mysql

1,759 views
1,655 views

Published on

0 Comments
14 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,759
On SlideShare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
112
Comments
0
Likes
14
Embeds 0
No embeds

No notes for slide

Optimzing mysql

  1. 1. Optimzing mysql
  2. 2. I feel the need....the need for speed. 壮志凌云( top gun )
  3. 3. <ul><li>性能监控 10 分 </li></ul><ul><li>性能优化 20 分 </li></ul><ul><li>常见的架构 10 分 </li></ul><ul><li>Tools and tips 10 分 </li></ul>
  4. 4. 性能监控 <ul><li>操作系统级别的 </li></ul><ul><li>Mysql 级别 </li></ul>
  5. 5. 操作系统 <ul><li>vmstat </li></ul><ul><li>iostat </li></ul><ul><li>free </li></ul><ul><li>top </li></ul><ul><li>sar </li></ul><ul><li>mpstat </li></ul><ul><li>uptime, </li></ul><ul><li>netstat </li></ul><ul><li>strace </li></ul>
  6. 6. mysql <ul><li>Show processlist </li></ul><ul><li>Mysqlreport http://hackmysql.com/mysqlreportguide </li></ul><ul><li>Mysqladmin -uxxx –p -i 1 -r extendedstatus|grep -v “| 0” </li></ul><ul><li>Innotop http://www.xaprb.com/blog/2006/07/02/innotop-mysql-innodb-monitor/ </li></ul><ul><li>Show global status,show inondb status show session status; </li></ul><ul><li>Mytop </li></ul><ul><li>Explain </li></ul><ul><li>Profiling </li></ul><ul><li>Mysqldumpslow mysqlsla </li></ul><ul><li>sysbench </li></ul>
  7. 7. vmstat <ul><li>基本的物理和虚拟内存的使用和一些基本的系统统计信息 </li></ul><ul><li>Vmstat –S M Vmstat 5 5 </li></ul><ul><li>Swap 颠簸现象 </li></ul><ul><li>Top ps axl </li></ul>
  8. 8. iostat <ul><li>度量磁盘 i/o,cpu 和设备 io 使用 </li></ul><ul><li>Iostat -c iostat –dx 5 </li></ul><ul><li>%iowait </li></ul><ul><li>并发请求的数量 </li></ul><ul><li>并发 = ( r/s+w/s ) *(svctm/1000)( 从头到尾服务请求时间 ) </li></ul>
  9. 9. Cpu 密集型机器
  10. 10. Io 密集型
  11. 11. Swap idle
  12. 12. <ul><li>谁可能导致高的 cpu usage </li></ul><ul><li>query , joins,every </li></ul><ul><li>进程切换, </li></ul><ul><li>锁表 </li></ul><ul><li>内存排序 </li></ul><ul><li>临时表 </li></ul><ul><li>加密算法 </li></ul><ul><li>谁可能导致高的 disk usage </li></ul><ul><li>临时表 </li></ul><ul><li>硬盘上排序 </li></ul><ul><li>start with an idea ,then look for infromation support it </li></ul>
  13. 13. netstat <ul><li>服务链接状态 </li></ul><ul><li>netstat -nat |awk '{print $6}' | sort | uniq -c | sort -n </li></ul><ul><li>是否被 dos : netstat -atun | awk '{print $5}' | cut -d: -f1 | sed -e '/^$/d' |sort | uniq -c | sort -n </li></ul><ul><li>/bin/netstat -na|grep ESTABLISHED|awk '{print $5}'|awk -F: '{print $1}'|sort|uniq -c|sort -rn|grep -v -E '172.16|127.0'|awk '{if ($2!=null && $1>10) {print $1,$2}}' </li></ul>
  14. 14. 其它 <ul><li>Top : </li></ul><ul><li>Ps : ps aux|awk '{ if ($6 >(1024*15)){print $2}}'|grep -v PID </li></ul><ul><li>……………… </li></ul>
  15. 15. 分析服务器 <ul><li>Mysqlreport </li></ul><ul><li>Mysqladmin mysqladmin extended -r -i 10| grep –v “| 0 ” -uroot –p </li></ul><ul><li>Innotop …. </li></ul><ul><li>Show global status </li></ul><ul><li>Show innodb status </li></ul>
  16. 16. 分析查询 <ul><li>Show processlist </li></ul><ul><li>Flush status </li></ul><ul><li>Show session status like ‘Select%’ </li></ul><ul><li>Show session status like ‘Handler%’ </li></ul><ul><li>Show session status like ‘Sort%’ </li></ul><ul><li>Show session status like ‘Create%’ </li></ul><ul><li>Set profiling </li></ul>
  17. 17. 分析 mysql 连接 <ul><li>netstat -ntp| grep :40327 </li></ul><ul><li>netstat -ntp| grep 10940/mysqld </li></ul><ul><li>grep 3306 /etc/services </li></ul><ul><li>ps -eaf| grep 'UID|10940' </li></ul><ul><li>lsof -i -P| grep 10942 </li></ul>
  18. 18. 性能优化 <ul><li>操作系统 </li></ul><ul><li>mysql </li></ul><ul><li>应用程序 </li></ul>
  19. 19. 操作系统 <ul><li>不要交换区。如果内存不足,增加更多的内存或配置你的系统使用较少内存。 </li></ul><ul><li>flick:echo 0 > /proc/sys/vm/swappiness </li></ul><ul><li>innodb_flush_method=O_DIRECT </li></ul><ul><li>不要使用 NFS 磁盘 ( 会有 NFS 锁定的问题 ) 。 </li></ul><ul><li>增加系统和 MySQL 服务器的打开文件数量。 ( 在 safe_mysqld 脚本中加入 ulimit -n #) 。 </li></ul><ul><li>增加系统的进程和线程数量。 </li></ul><ul><li>选择使用哪种文件系统。在 Linux 上的 Reiserfs 对于打开、读写都非常快。文件检查只需几秒种。 </li></ul>
  20. 20. Mysql 配置 <ul><li>Mysiam 缓存 </li></ul><ul><li>key_buffer_size </li></ul><ul><li>key_buffer_1.key_buffer_size=1G </li></ul><ul><li>show variables like 'key_buffer_size'; </li></ul><ul><li>show global status like 'key_read%'; </li></ul><ul><li>key_cache_miss_rate = Key_reads / Key_read_requests * 100% </li></ul><ul><li>du –sch `find /mysqldatapath/ -name “*.MYI”` </li></ul><ul><li>Innodb 缓冲池 </li></ul><ul><li>innodb_bufer_pool_size 80% </li></ul><ul><li>show status like 'Innodb_buffer_pool_read%' </li></ul><ul><li>Innodb_buffer_pool_read_requests/Innodb_buffer_pool_reads </li></ul><ul><li>show innodb statusG </li></ul><ul><li>BUFFER POOL AND MEMORY Total memory allocated 4668764894; </li></ul>
  21. 21. 查询缓存 <ul><li>show global status like 'Qcache%'; </li></ul><ul><li>show variables ‘like query_cache%'; </li></ul><ul><li>查询缓存利用率 = (query_cache_size – Qcache_free_memory) / query_cache_size * 100% </li></ul><ul><li>查询缓存命中率 = (Qcache_hits – Qcache_inserts) / Qcache_hits * 100% </li></ul><ul><li>http://www.day32.com/MySQL/ </li></ul>
  22. 22. innodb <ul><li>刷写日志缓冲 </li></ul><ul><li>Innodb_flush_log_at_trx_commit 0 1 2 </li></ul><ul><li>打开并清写日志和文件 </li></ul><ul><li>innodb_flush_method </li></ul>
  23. 23. myisam <ul><li>初始化: </li></ul><ul><li>initial =key_buffer_size + query_cache_size </li></ul><ul><li>连接 </li></ul><ul><li>per_connection=(sort_buffer_size +read_rnd_buffer_size + join_buffer_size + read_buffer_size + thead_stack ) </li></ul><ul><li>总和: </li></ul><ul><li>initial + max_connections * per_connection </li></ul><ul><li>initial + ((max_connections * per_connection)/3) </li></ul>
  24. 24. innodb <ul><li>初始化: </li></ul><ul><li>initial =innodb_buffer_pool_size + query_cache_size </li></ul><ul><li>连接 </li></ul><ul><li>per_connection = (sort_buffer_size + join_buffer_size + thead_stack + binlog_cache_size + read_buffer_size + read_rnd_buffer_size) </li></ul><ul><li>总和: </li></ul><ul><li>initial + max_connections * per_connection </li></ul><ul><li>initial + ((max_connections * per_connection)/3) </li></ul>
  25. 25. 数据类型选择 <ul><li>更小通常更好 , 慷慨并不明智 </li></ul><ul><li>简单就好 </li></ul><ul><li>使用 mysql 内建的类型保存日期和时间,使用 timestamp 保存,空间是 datetime 一半 </li></ul><ul><li>使用整数保存 ip </li></ul><ul><li>15 bytes for char(15) vs. 4 bytes for the integer </li></ul><ul><li>ip2long() 和 long2ip() inet_aton </li></ul><ul><li>3 尽量避免 null </li></ul><ul><li>4 Char /varcha 的选择 </li></ul><ul><li>对于 MyISAM 而言,如果没有 VARCHAR , TEXT 等变长类型,那么每行数据所占用的空间都是定长的( Fixed ),俗称静态表,相对应的就是动态表。当执行一次查询时, MySQL 可以通过索引文件找到所需内容的实际行号,此时,由于每行数据所占用的空间都是定长的( Fixed ),所以可以通过查询到的实际行号直接定位到数据文件的具体位置, </li></ul><ul><li>对于 InnoDB 而言,数据行是没有所谓定长与否的概念的,这是由其结构所决定的:在 InnoDB 中,数据就位于 Primary Key 的 B-Tree 叶节点之上而除 Primary Key 之外的索引被称为 Secondary Index ,它们直接指向 Primary Key 。 </li></ul><ul><li>用 char 来代替 varchar , MyISAM 是这样, InnoDB 则相反 </li></ul><ul><li>5 使用 enum 代替字符串类型 select internet + 0 from hotel_info group by internet; </li></ul>
  26. 26. 索引 <ul><li>隔离列 </li></ul><ul><ul><li>select * from tablename where id+1=5 </li></ul></ul><ul><ul><li>Select * where TO_DAYS(CURRENT_DATE) – TO_DAYS(data_col) < =10 </li></ul></ul><ul><ul><li>Select * where data_col >=date_sub(current_date,interval 10 day) </li></ul></ul><ul><ul><li>Select * where data_col >= date_sum(‘2010-04-12’,interval 10 day) </li></ul></ul><ul><ul><li>EXPLAIN SELECT * FROM film WHERE title LIKE 'Tr%'G </li></ul></ul><ul><ul><li>EXPLAIN SELECT * FROM film WHERE LEFT(title,2) = 'Tr' G </li></ul></ul><ul><li>组合索引 前缀索引 </li></ul><ul><li>覆盖索引 </li></ul><ul><li>合并索引 </li></ul><ul><li>去除多余索引和重复索引 create table test (id int not null primary key, unique(id), </li></ul><ul><li>index(id) </li></ul><ul><li>) </li></ul>
  27. 27. 合并索引 <ul><li>索引合并 方法用于通过 range 扫描搜索行并将结果合成一个。合并会产 生并集、交集或者正在进行的扫描的交集的并集。 </li></ul><ul><li>在 EXPLAIN 输出中,该方法表现为 type 列内的 index_merge 。 在这种情况下, key 列包含一列使用的索引, key_len 包含这些索引的最长的关键元素 </li></ul>SELECT * FROM tbl_name WHERE key_part1 = 10 OR key_part2 = 20;
  28. 28. 前缀索引 <ul><li>Key(a,b,c) </li></ul><ul><li>Order by a ,order by a,b order by a,b,c order by a desc ,b desc,c desc </li></ul><ul><li>Where a = const order by b,c,where a=const and b =const order by c </li></ul><ul><li>Where a = const order by b,c where a = const and b > const order by,c </li></ul><ul><li>Order by a asc,b desc,c desc </li></ul><ul><li>Where g = const oder by b ,c </li></ul><ul><li>Where a = const order by c </li></ul><ul><li>Where a = const order by a ,d </li></ul><ul><li>Where a>’xx’ order by b,c </li></ul><ul><li>Where a>’xx’ order by a,b </li></ul><ul><li>Where a=const order by b desc ,a asc </li></ul>
  29. 29. 覆盖索引 <ul><li>Select * from products where actor=‘sean carrey’ and and title like ‘%apollo%’ </li></ul><ul><li>Select * from products join (select prod_id from products where actor= ‘sean carrey’ and title like ‘%apollo%’) as t1 on (t1.prod_id = products.pro_id) </li></ul>
  30. 30. 逆范式化 <ul><li>适当的冗余 </li></ul><ul><li>分拆表 </li></ul>
  31. 31. 产品设计 <ul><li>产品设计 -> 数据交互 ->mysql </li></ul><ul><li>Antoine de Saint—Exupery 是法国作家兼飞机设计师,他曾经说过:“设计者确定其设计已经达到了完美的标准不是不能再增加任何东西,而是不能再减少任何东 西。” </li></ul><ul><li>分页的实现 </li></ul>
  32. 32. http://www.douban.com/group/BigBangTheory/discussion?start=25
  33. 33. <ul><li>1 explain select SQL_NO_CACHE * from page_test force index(idx_b_c) where b=1 order by c desc limit 2000,10; </li></ul><ul><li>+----+-------------+-----------+------+---------------+---------+---------+-------+------+-------------+ </li></ul><ul><li>| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | </li></ul><ul><li>+----+-------------+-----------+------+---------------+---------+---------+-------+------+-------------+ </li></ul><ul><li>| 1 | SIMPLE | page_test | ref | idx_b_c | idx_b_c | 4 | const | 2222 | Using where | </li></ul><ul><li>+----+-------------+-----------+------+---------------+---------+---------+-------+------+-------------+ </li></ul><ul><li>2 </li></ul><ul><li>mysql> explain select SQL_NO_CACHE * from page_test, (select SQL_NO_CACHE id from page_test force index(idx_b_c) where b=1 order by c desc limit 2000,10) temp where page_test.id=temp.id; </li></ul><ul><li>+----+-------------+------------+--------+---------------+---------+---------+---------+------+--------------------------+ </li></ul><ul><li>| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | </li></ul><ul><li>+----+-------------+------------+--------+---------------+---------+---------+---------+------+--------------------------+ </li></ul><ul><li>| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 10 | | </li></ul><ul><li>| 1 | PRIMARY | page_test | eq_ref | PRIMARY | PRIMARY | 8 | temp.id | 1 | | </li></ul><ul><li>| 2 | DERIVED | page_test | ref | idx_b_c | idx_b_c | 4 | | 2222 | Using where; Using index | </li></ul><ul><li>+----+-------------+------------+--------+---------------+---------+---------+---------+------+--------------------------+ </li></ul><ul><li>3 explain select SQL_NO_CACHE * from page_test force index(idx_b_id) where b=1 and id<187796 order by id desc limit 10; </li></ul><ul><li>+----+-------------+-----------+-------+---------------+----------+---------+------+------+-------------+ </li></ul><ul><li>| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | </li></ul><ul><li>+----+-------------+-----------+-------+---------------+----------+---------+------+------+-------------+ </li></ul><ul><li>| 1 | SIMPLE | page_test | range | idx_b_id | idx_b_id | 12 | NULL | 190 | Using where | </li></ul><ul><li>+----+-------------+-----------+-------+---------------+----------+---------+------+------+-------------+ </li></ul><ul><li>5 select SQL_NO_CACHE * from page_test force index(idx_b_c) where b=1 order by c desc 870,10 </li></ul><ul><li>select SQL_NO_CACHE * from page_test force index(idx_b_c) where b=1 order by c asc 9120,10 </li></ul><ul><li>./tuning-primer.sh all </li></ul>
  34. 34. 优化 count(*) <ul><li>Mysiam: </li></ul><ul><li>select sql_no_cache count(*) from statistic_go where id > 10; </li></ul><ul><li>select sql_no_cache (select count(*) from statistic_go) - count(*) from statistic_go where id <=10; </li></ul><ul><li>Innodb  : </li></ul><ul><li>在缺少 where 字句的情况下, InnoDB 不对 count(*) 查询进行优化–这个是事实。 SELECT COUNT(*) FROM sbtest1 WHERE id>=0; </li></ul><ul><li>建立计数器触发器 </li></ul><ul><li>对同一个表的 select 和 update </li></ul><ul><li>update hotel_image inner join (select count(*) as cnt from hotel_image) as der set hotel_image.size = der.cnt; </li></ul>
  35. 36. 其它一些 <ul><li>Group by 不进行排序,可以 ordery by null </li></ul><ul><li>能够快速缩小结果集的 WHERE 条件写在前面,如果有恒量条件,也尽量放在前面 </li></ul><ul><li>使用 UNION 来取代 IN 和 OR </li></ul><ul><li>定期执行 optimize / analyze table </li></ul><ul><li>往 innoDB 表导入数据时,先关闭 autocommit 模式,否则会实时刷新数据到磁盘 </li></ul><ul><li>对于频繁更改的 MyISAM 表 , 应尽量避免更新所有变长字段 (VARCHAR 、 BLOB 和 TEXT) </li></ul><ul><li>分表 分库 </li></ul><ul><li>汇总表 十大热门话题 create table hotel_infonew like hotel_info; rename table hotel_info to hotel_info_old ,hotel_infonew to hotel_info </li></ul><ul><li>放弃关系型数据库 key=>value ,计数表 </li></ul>
  36. 37. 常见架构方案 <ul><li>Replication </li></ul><ul><li>双 master </li></ul><ul><li>集群。。。。。 </li></ul>
  37. 38. replication <ul><li>1 数据分发 ,scale out , sacle up </li></ul><ul><li>2 负载均衡 load balance </li></ul><ul><li>3 备份,一般不会用作备份,一旦执行 delete 操作, replication 也不会保留 </li></ul><ul><li>4 高可用 </li></ul><ul><li>5 可以在不同的主从库上使用不同的存储引擎 </li></ul>
  38. 40. 原理
  39. 41. <ul><li>简单的讲就是 master 记录其变化到 binlog , slave 接收到变化后会记录到他的 Relay log , slave 通过重放 relay log ,然后就写进自己的 log 1) 、 Slave 上面的 IO 进程连接上 Master ,并请求从指定日志文件的指定位置(或者从最开始的日志)之后的日志内容; 2) 、 Master 接收到来自 Slave 的 IO 进程的请求后,通过负责复制的 IO 进程根据请求信息读取制定日志指定位置之后的日志信息,返回给 Slave 的 IO 进程。返回信息中除了日志所包含的信息之外,还包括本次返回的信息已经到 Master 端的 bin-log 文件的名称以及 bin-log 的位置; 3) 、 Slave 的 IO 进程接收到信息后,将接收到的日志内容依次添加到 Slave 端的 relay-log 文件的最末端,并将读取到的 Master 端的 bin-log 的文件名和位置记录到 master-info 文件中,以便在下一次读取的时候能够清楚的高速 Master“ 我需要从某个 bin-log 的哪 个位置开始往后的日志内容,请发给我”; 4) 、 Slave 的 Sql 进程检测到 relay-log 中新增加了内容后,会马上解析 relay-log 的内容成为在 Master 端真实执行时候的那些可执行的内容,并在自身执行 </li></ul>
  40. 42. 常见问题 <ul><li>延迟 </li></ul><ul><li>主从不同步 </li></ul><ul><li>命令复制 基于行复制 </li></ul>
  41. 43. 高可用 <ul><li>通过 Heartbert2 让 Mysql Replication 具有 HA </li></ul>
  42. 44. 双 master
  43. 45. 工具 <ul><li>Innotop </li></ul><ul><li>Maatkit </li></ul><ul><li>mk-table-checksum </li></ul><ul><li>mk-table-sync </li></ul><ul><li>mk-parallel-dump </li></ul><ul><li>mk-parallel-restore </li></ul><ul><li>mk-find </li></ul><ul><li>Optimize table 脚本 </li></ul>
  44. 46. Tools and tips <ul><li>h 命令 </li></ul><ul><li>大批量数据的导入 </li></ul><ul><li>load data infile ‘/path/to/file’ into table tbl_name; </li></ul><ul><li>alter table tbl_name disable keys; </li></ul><ul><li>alter table tbl_name enable keys; </li></ul><ul><li>快速复制表结构: </li></ul><ul><li>create table clone_tbl select * from tbl_name limit 0 </li></ul><ul><li>Gdb 更改 mysql 配置 </li></ul><ul><li>show variables like 'log_slave_updates'; set global log_slave_updates=1; </li></ul><ul><li>system gdb -p $(pidof mysqld) -ex &quot;set opt_log_slave_updates=1&quot; -batch </li></ul><ul><li>gdb -p $(pidof mysqld) -ex &quot;set max_connections=5000&quot; -ex &quot;call resize_thr_alarm(5030)&quot; -batch </li></ul><ul><li>truncate table 不能复制到从库 </li></ul><ul><li>perl -ne ‘m/^([^#][^s=]+)s*(=.*|)/ && printf(“%-35s%s ”, $1, $2)’ /etc/mysql/my.cnf 美化 my.cnf </li></ul><ul><li>加快 alter table </li></ul><ul><li>Dump 文件中找出 create table sed -e '/./{H;$!d;}' -e 'x;/CREATE TABLE `hotel_info`/!d;q' hotel_new2010-3-1117.sql </li></ul>
  45. 47. 同一个团队,同一个梦想 Thanks!

×