Archive for the ‘MySQL’ Category

高效的MySQL分页

Wednesday, April 29th, 2009

PERCONA PERFORMANCE CONFERENCE 2009上,来自雅虎的几位工程师带来了一篇"Efficient Pagination Using MySQL"的报告,有很多亮点,本文是在原文基础上的进一步延伸。 首先看一下分页的基本原理: mysql> explain SELECT * FROM message ORDER BY id DESC LIMIT 10000, 20\G ***************** 1. row ************** id: 1 select_type: SIMPLE table: message type: index possible_keys: NULL key: PRIMARY key_len: 4 ref: NULL rows: 10020 Extra: 1 row in set (0.00 sec) limit 10000,20的意思扫描满足条件的10020行,扔掉前面的10000行,返回最后的20行,问题就在这里,如果是limit 100000,100,需要扫描100100行,在一个高并发的应用里,每次查询需要扫描超过10W行,性能肯定大打折扣。文中还提到limit n性能是没问题的,因为只扫描n行。 文中提到一种"clue"的做法,给翻页提供一些"线索",比如还是SELECT * FROM message ORDER BY id DESC,按id降序分页,每页20条,当前是第10页,当前页条目id最大的是9527,最小的是9500,如果我们只提供"上一页"、"下一页"这样的跳转(不提供到第N页的跳转),那么在处理"上一页"的时候SQL语句可以是: SELECT * FROM message WHERE ...

根据status信息对MySQL服务器进行优化(二)

Wednesday, March 25th, 2009

续根据status信息对MySQL服务器进行优化(一),直入主题。 六、进程使用情况 mysql> show global status like 'Thread%'; +-------------------+-------+ | Variable_name     | Value | +-------------------+-------+ | Threads_cached    | 46    | | Threads_connected | 2     | | Threads_created   | 570   | | Threads_running   | 1     | +-------------------+-------+ 如果我们在MySQL服务器配置文件中设置了thread_cache_size,当客户端断开之后,服务器处理此客户的线程将会缓存起来以响应下一个客户而不是销毁(前提是缓存数未达上限)。Threads_created表示创建过的线程数,如果发现Threads_created值过大的话,表明MySQL服务器一直在创建线程,这也是比较耗资源,可以适当增加配置文件中thread_cache_size值,查询服务器thread_cache_size配置: mysql> show variables like 'thread_cache_size'; +-------------------+-------+ | Variable_name     | Value | +-------------------+-------+ | thread_cache_size | 64    | +-------------------+-------+ 示例中的服务器还是挺健康的。 七、查询缓存(query cache) mysql> show global status like 'qcache%'; +-------------------------+-----------+ | Variable_name           | Value     | +-------------------------+-----------+ | Qcache_free_blocks      ...

根据status信息对MySQL服务器进行优化(一)

Tuesday, March 24th, 2009

网上有很多的文章教怎么配置MySQL服务器,但考虑到服务器硬件配置的不同,具体应用的差别,那些文章的做法只能作为初步设置参考,我们需要根据自己的情况进行配置优化,好的做法是MySQL服务器稳定运行了一段时间后运行,根据服务器的"状态"进行优化。 mysql> show global status; 可以列出MySQL服务器运行各种状态值,另外,查询MySQL服务器配置信息语句: mysql> show variables; 一、慢查询 mysql> show variables like '%slow%'; +------------------+-------+ | Variable_name    | Value | +------------------+-------+ | log_slow_queries | ON    | | slow_launch_time | 2     | +------------------+-------+ mysql> show global status like '%slow%'; +---------------------+-------+ | Variable_name       | Value | +---------------------+-------+ | Slow_launch_threads | 0     | | Slow_queries        | 4148 | +---------------------+-------+ 配置中打开了记录慢查询,执行时间超过2秒的即为慢查询,系统显示有4148个慢查询,你可以分析慢查询日志,找出有问题的SQL语句,慢查询时间不宜设置过长,否则意义不大,最好在5秒以内,如果你需要微秒级别的慢查询,可以考虑给MySQL打补丁:http://www.percona.com/docs/wiki/release:start,记得找对应的版本。 打开慢查询日志可能会对系统性能有一点点影响,如果你的MySQL是主-从结构,可以考虑打开其中一台从服务器的慢查询日志,这样既可以监控慢查询,对系统性能影响又小。 二、连接数 经常会遇见"MySQL: ERROR 1040: Too many connections"的情况,一种是访问量确实很高,MySQL服务器抗不住,这个时候就要考虑增加从服务器分散读压力,另外一种情况是MySQL配置文件中max_connections值过小: mysql> show variables like 'max_connections'; +-----------------+-------+ | Variable_name   | ...

我也不知道的MySQL

Friday, March 13th, 2009

以前看过很多文章说MySQL一次查询只能用到一个索引,在实践中也没注意,一直奉为金科玉律,以此教育自己不要乱建索引,殊不知已是明日黄花。 MySQL5.0以后引入了index_merge,在一些特定的查询中可以合并索引,详细的内容查看[中文] [英文],接着测试一下,还是那张表,数据还是10,000条。 mysql> desc tbl_name; +-------+--------------+------+-----+---------+-------+ | Field | Type         | Null | Key | Default | Extra | +-------+--------------+------+-----+---------+-------+ | uid   | int(11)      | NO   | MUL | NULL    |       | | sid   | mediumint(9) | NO   |     | NULL    |       | | times | mediumint(9) | NO   |     | NULL    |       | +-------+--------------+------+-----+---------+-------+ 3 rows in set ...

你可能不知道的MySQL

Wednesday, March 11th, 2009

前言: 实验的数据表如下定义: mysql> desc tbl_name; +-------+--------------+------+-----+---------+-------+ | Field | Type         | Null | Key | Default | Extra | +-------+--------------+------+-----+---------+-------+ | uid   | int(11)      | NO   |     | NULL    |       | | sid   | mediumint(9) | NO   |     | NULL    |       | | times | mediumint(9) | NO   |     | NULL    |       | +-------+--------------+------+-----+---------+-------+ 3 rows in set (0.00 sec) 存储引擎是MyISAM,里面有10,000条数据。 一、"\G"的作用 mysql> ...

改善MySQL上16进制标识符性能的5种方法

Friday, February 13th, 2009

前言: 原文地址:5 ways to make hexadecimal identifiers perform better on MySQL,作者是《High Performance MySQL, Second Edition.》的主要作者。这里是原文的节译。 在我们的业务中,经常会用md5()或者uuid()作为作为数据的标识,比如B2C网站,经常会有一些电子优惠券,常用就是通过md5()获得一个32位字符串,给字符串建立索引,然后用户输入优惠券代码之后系统查出此优惠券对应的折扣率:select discount from coupon where id = '0cc175b9c0f1b6a831c399e269779527',这样的做法存在两个问题:数据和索引很大以及非顺序数据,本文忽略“非顺序数据”的问题,因为顺序数据和非顺序数据的优劣很大程度上由技术特性决定。这里讲得是如何在使用16进制大数据的情况下保持好的性能,主要讲的是MySQL数据库,对其他数据库应该也起作用。 一、小心你的字符编码 看一下下面这个SQL语句: mysql> explain select * from t where id = '0cc175b9c0f1b6a831c399e269772661'\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: t type: const possible_keys: PRIMARY key: PRIMARY key_len: 98 ref: const rows: 1 Extra: Using index 为什么索引是98byte?简单,因为我们用的是UTF-8: CREATE TABLE `t` ( `id` varchar(32) NOT NULL, PRIMARY ...

基于Infobright的MySQL数据仓库方案测试

Tuesday, February 10th, 2009

数据仓库之父Bill Inmon在1991年出版的“Building the Data Warehouse”一书中所提出的定义被广泛接受——数据仓库(Data Warehouse)是一个面向主题的(Subject Oriented)、集成的(Integrated)、相对稳定的(Non-Volatile)、反映历史变化(Time Variant)的数据集合,用于支持管理决策(Decision Making Support)。 上面这段是抄的,简单的讲数据仓库是一个面向主题的、集成的、不可更新的、随时间不断变化的数据集合,它用于支持企业或组织的决策分析处理,这一句也是抄的,更直白的举例就是公司的历史交易数据集合,网站的历史访问数据集合,这一句是原创的。 Infobright是开源的MySQL数据仓库解决方案,引入了列存储方案,高强度的数据压缩,优化的统计计算(类似sum/avg/group by之类),下面是Infobright的架构图: 安装篇: Infobright目前还不支持windows系列操作系统,不过你可以装在Linux虚拟机上,或者从官方直接下载做好的VMWARE虚拟机,这里的测试环境是CentOS 5.2 32bit操作系统。Infobright也不支持以插件的形式集成到已有的MySQL系统中去,官方的说法是对MySQL做了很多修改,不支持以插件的形式使用。 详细的安装参照http://www.infobright.org/wiki/Install_Guide/,需要注意的是如果你的系统中已经有MySQL(默认端口3306),你需要重新设定一下安装参数,比如像我的: ./install-infobright.sh --datadir=/data/infobright/data --cachedir=/data/infobright/cache --port=9527 --config=/etc/my-ib.cnf --socket=/tmp/mysql-ib.sock --user=mysql --group=mysql 配置文件包括MySQL配置文件(/etc/my-ib.cnf)和Infobright配置文件(在安装时候指定的数据目录内,比如/data/infobright/data/brighthouse.ini),如果需要支持MySQL原生的SQL查询,需要修改brighthouse.ini设定 AllowMySQLQueryPath = 1 这样不至于有些SQL语句不能执行,安装完成,启动服务: /etc/init.d/mysqld-ib start 通过命令行:mysql-ib -uroot直接连接,默认密码为空,修改密码: /usr/local/infobright/bin/mysqladmin  -u root -p password NEWPASSWORD 测试篇: 测试数据是一个1.5GB大的文本数据,数据格式类似: 用户ID  内容ID  用户打分 765331  3868    5 716091  3868    3 1663216 3868    3 51971   3868    5 在测试数据库中新建两张表,一个为Infobright支持的brighthouse存储引擎,一个为MySQL原生的MyISAM存储引擎,其他内容一致: CREATE TABLE `t_ib` ( `uid` mediumint(9) NOT NULL, `cid` smallint(6) NOT NULL, `rating` tinyint(4) NOT ...

MySQL统计函数GROUP_CONCAT陷阱

Saturday, December 13th, 2008

本博客所有原创文章采用知识共享署名-非商业性使用-相同方式共享,转载请保留链接http://chaoqun.17348.com/2008/12/mysql-trap-of-group-concat/ 最近在用MySQL做一些数据的预处理,经常会用到group_concat函数,比如类似下面一条语句 mysql>select aid,group_concat(bid) from tbl group by aid limit 1; sql语句比较简单,按照aid分组,并且把相应的bid用逗号串起来。这样的句子大家可能都用过,也可能不会出问题,但是如果bid非常多的话,你就要小心了,比如下面的提示信息: Query OK, XXX rows affected, 1 warning (3 min 45.12 sec) 怎么会有警告呢,打出来看看: mysql> show warnings; +---------+------+-----------------------------------------+ | Level   | Code | Message                                 | +---------+------+-----------------------------------------+ | Warning | 1260 | 1 line(s) were cut by GROUP_CONCAT() | +---------+------+-----------------------------------------+ 居然被GROUP_CONCAT截断了我的结果,查了一下手册,原来GROUP_CONCAT有个最大长度的限制,超过最大长度就会被截断掉,你可以通过下面的语句获得: mysql> SELECT @@global.group_concat_max_len; +-------------------------------+ | @@global.group_concat_max_len | +-------------------------------+ |                      1024 | +-------------------------------+ 1024这就是一般MySQL系统默认的最大长度,如果你的bid串起来大于这个就会出问题,好在有解决的办法: 1.在MySQL配置文件中加上 group_concat_max_len ...

MySQL数据类型迷惑之整型xxxINT

Friday, November 7th, 2008

本博客所有原创文章采用知识共享署名-非商业性使用-相同方式共享,转载请保留链接http://chaoqun.17348.com/2008/11/mysql-data-types-int/ 最近在做一些利用MySQL进行数据挖掘方面的尝试,处理的大多是海量的数据(一般是5000W条以上),由于数据量巨大,数据库表字段数据类型的选择就显示出重要性来了。 比如有下面的一个表: mysql> desc test; +--------+---------+------+-----+---------+-------+ | Field  | Type    | Null | Key | Default | Extra | +--------+---------+------+-----+---------+-------+ | uid    | int(11) | NO   |     | NULL    |       | | cid    | int(11) | NO   |     | NULL    |       | | rating | int(11) | NO   |     | NULL    |       | | day    | date    | NO   ...

OpenSlopeOne: An Open Source Project implementing Slope One in PHP&MySQL

Friday, September 12th, 2008

About OpenSlopeOne OpenSlopeOne is an implementation of Slope One based on PHP&MySQL, it's an open source project under GPL V3. It aims to a fast way to use Slope One with PHP&MySQL, and it can handle tons of data. It's localed on Google Code:     http://code.google.com/p/openslopeone/ You can get the latest code here:     svn checkout ...