MySQL-老生常谈的问题了,依然没完美解决!~mysql多表联合查询该如何做分页优化?
现有一日志表,数据增长到了千万级,查询分页到后面几页会非常慢,想做下优化,可不知如何下手,甚是困顿啊!
表结构与查询语句如下,做了下简化:
-- 主要log表 无连续性增长字段
CREATE TABLE `data_log` (
`uniqueid` varchar(20) NOT NULL,
`lead_id` int(9) unsigned NOT NULL,
`event_time` datetime DEFAULT NULL,
`length_in_sec` int(10) DEFAULT NULL,
`status` varchar(6) DEFAULT NULL,
`user` varchar(20) DEFAULT NULL,
`comments` varchar(36) DEFAULT 'AUTO',
PRIMARY KEY (`uniqueid`),
KEY `lead_id` (`lead_id`),
KEY `event_time` (`event_time`),
KEY `status` (`status`),
KEY `user` (`user`),
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `data_users` (
`user_id` int(9) unsigned NOT NULL AUTO_INCREMENT,
`user` varchar(20) NOT NULL,
`pass` varchar(20) NOT NULL,
`full_name` varchar(50) DEFAULT NULL,
`user_level` tinyint(2) DEFAULT '1',
`user_group` varchar(20) DEFAULT NULL,
PRIMARY KEY (`user_id`),
UNIQUE KEY `user` (`user`)
) ENGINE=MyISAM AUTO_INCREMENT=15 DEFAULT CHARSET=utf8
CREATE TABLE `data_status` (
`status` varchar(20) NOT NULL,
`status_name` varchar(50) DEFAULT NULL,
PRIMARY KEY (`status`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
mysql> EXPLAIN
-> select a.lead_id,a.call_date,a.user,b.full_name,a.status,c.status_name from data_log a
-> left join data_users b on a.user=b.user
-> left join data_status c on a.status=c.status
-> where a.event_time BETWEEN '2014-02-12 10:00:01' and '2014-02-12 23:00:01'
-> and a.status='NA' order by a.event_time desc limit 10000,10050;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,我觉得索引没有问题。
以下是个人分析,仅供参考
1/ 如果每次查询的时间跨度比较小或者小的占多数,可以考虑按照时间分表(粒度根据具体场景
来定),这样可以减少表容量,从而提高查询速度
2/ 表结构和字段类型 时间短,我只能把我看到的说下
既然冗余,那data_log是否可以不用user而只用user_id, a.status 和c.status 用
tinyint或者int或者enum是否可以代替。
data_status我的理解应该是类似于数据字典,那这个是否可以直接存放到缓存里,在程
序端来通过映射来实现页面的显示,这样就少join一个表。
myisam引擎下char要比varchar有更好的查询性能
3/ limit offset,limit_number 是否可以写为 where id>offset limit limit_number