| Subcribe via RSS

MySQL performance tuning primer script 中文注释版

11月 11th, 2008 | 1 Comment | Posted in MySQL < by Martian Guo >

mysql tuner-primer 是一个比较简单好用的检查mysql运行状态的shell脚本,它主要通过查询mysql中的variables设定和status 并结合当前系统情况给出mysql运行的状态和建议,主要包括以下内容的检查
slow query慢速查询
binlog 二进制日志
max connections 最大连接数
threads 线程数
key buffer size 关键字缓冲
query cache 查询缓存
sort operations 排序
join operations 多表联接
tmp tables 临时表
open files 打开文件数
table cache 表缓存
table locking 锁表
table scans 表扫描
innodb status
total memory used 内存使用

文件下载:tuning-primer

阅读内文 Tags: ,

Mysql数据库索引查询优化的分享

8月 11th, 2008 | 10 Comments | Posted in MySQL < by Michael Field >

问题描述:
我们要访问的表是一个非常大的表,四千万条记录,id是主键,program_id上建了索引。
执行一条SQL:

select * from program_access_log where program_id between 1 and 4000

这条SQL非常慢。
我们原以为处理记录太多的原因,所以加了id限制,一次只读五十万条记录

select * from program_access_log where id between 1 and 500000 and program_id between 1 and 4000

但是这条SQL仍然很慢,速度比上面一条几乎没有提升。
Mysql处理50万条记录的表,条件字段还建了索引,这条语句应该是瞬间完成的。

问题分析:
这张表大约容量30G,数据库服务器内存16G,无法一次载入。就是这个造成了问题。
这条SQL有两个条件,ID一到五十万和Program_id一到四千,因为program_id范围小得多,mysql选择它做为主要索引。
先通过索引文件找出了所有program_id在1到4000范围里所有的id,这个过程非常快。
接下来要通过这些id找出表里的记录,由于这些id是离散的,所以mysql对这个表的访问不是顺序读取。
而这个表又非常大,无法一次装入内存,所以每访问一条记录mysql都要重新在磁盘上定位并把附近的记录都载入内存,大量的IO操作导致了速度的下降。

问题解决方案:
1. 以program_id为条件对表进行分区
2. 分表处理,每张表的大小不超过内存的大小
然而,服务器用的是mysql5.0,不支持分区,而且这个表是公共表,无法在不影响其它项目的条件下修改表的结构。
所以我们采取了第三种办法:

select * from program_access_log where id between 1 and 500000 and program_id between 1 and 15000000

现在program_id的范围远大于id的范围,id被当做主要索引进行查找,由于id是主键,所以查找的是连续50万条记录,速度和访问一个50万条记录的表基本一样

总结:
这是一个在千万笔记录表中由于使用了索引导致了数据查找变慢的问题,有一定的典型性和大家交流下!

阅读内文 Tags: , , ,