MySQL分页优化(SQL篇)
Friday, March 5th, 2010上文提到可以通过去除跳页和限制翻页来减少整个系统的压力。然而PD往往会考虑到用户体验,不愿意去推动这种功能上的删减。
家家有本难念的经,可以理解PD的苦衷。那么作为一个DBA,就只能从SQL上去优化分页的性能了。
假设我们有一个需要分页的表,如下:
CREATE TABLE `test` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`b` int(11) NOT NULL,
`c` datetime NOT NULL,
`d` varchar(1000) NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_b_c` (`b`,`c`),
KEY `idx_b_id` (`b`,`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
ID为自增,b为随机数,c为递增的时间,d为长度1000的字符串。往里面插入200w+数据。
典型的分页语句如下:
SQL1:select SQL_NO_CACHE * from test force index(idx_b_c) where b=1 order by c desc limit 2000,10
在六块磁盘做RAID10的情况下,SQL1需要耗费6s以上。explain SQL1可以得到以下结果:
+—-+————-+——-+——+—————+———+———+——-+——+————-+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+—-+————-+——-+——+—————+———+———+——-+——+————-+
| 1 | SIMPLE | test | ref | idx_b_c | idx_b_c | 4 | const | 2574 | Using where |
+—-+————-+——-+——+—————+———+———+——-+——+————-+
using where表示MySQL从InnoDB获取了数据之后还要根据条件进行筛选,也就是limit 2000,10那部分。 (more…)