表结构:
CREATE TABLE `p_account_log` (
`
log_id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`
uid` mediumint(8) unsigned NOT NULL COMMENT '会员编号',
`
use_money` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '可用资金',
`
change_time` int(10) unsigned NOT NULL COMMENT '变动时间',
`
change_desc` varchar(255) NOT NULL DEFAULT '' COMMENT '备注',
`
change_type` tinyint(3) unsigned NOT NULL COMMENT '变动类型0为充值,1为消费, 2为充值会员 3为推荐奖励 99为其他',
PRIMARY KEY (`log_id`),
KEY `user_id` (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=82416 DEFAULT CHARSET=utf8 COMMENT='账户变动记录表';
CREATE TABLE `p_order` (
`
order_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`
uid` int(11) DEFAULT '0' COMMENT '会员编号',
`
username` varchar(30) DEFAULT '' COMMENT '会员名',
`
courier_id` int(11) DEFAULT '0' COMMENT '快递ID',
`
courier_name` varchar(180) DEFAULT '' COMMENT '快递名称',
`
sum_money` decimal(10,2) DEFAULT '0.00' COMMENT '付款金额',
`
order_status` tinyint(1) DEFAULT '0' COMMENT '订单状态',
`
pay_status` tinyint(1) DEFAULT '0' COMMENT '付款状态',
`
add_time` int(10) DEFAULT '0' COMMENT '添加时间',
`
pay_time` int(10) DEFAULT '0' COMMENT '付款时间',
`
sender_name` varchar(30) DEFAULT '' COMMENT '发件人姓名',
`
sender_province` varchar(30) DEFAULT '' COMMENT '发件人省份',
`
sender_city` varchar(30) DEFAULT NULL COMMENT '发件人城市',
`
sender_district` varchar(30) DEFAULT '' COMMENT '发件人地区',
`
sender_address` varchar(180) DEFAULT '' COMMENT '发件人详细地址',
`
sender_zip` varchar(10) DEFAULT '' COMMENT '邮政编码',
`
sender_mobile` varchar(20) DEFAULT '' COMMENT '发件人手机',
`
sender_telphone` varchar(20) DEFAULT '' COMMENT '发件人座机',
PRIMARY KEY (`order_id`)
) ENGINE=InnoDB AUTO_INCREMENT=63284 DEFAULT CHARSET=utf8 COMMENT='订单表';
CREATE TABLE `p_user` (
`
uid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`
username` varchar(30) DEFAULT '' COMMENT '用户名',
`
password` varchar(32) DEFAULT '' COMMENT '密码',
`
mobile` varchar(20) DEFAULT '' COMMENT '手机号',
`
qq` varchar(20) DEFAULT '' COMMENT 'QQ',
`
email` varchar(160) DEFAULT '' COMMENT '电子邮件',
`
amount` decimal(10,2) DEFAULT '0.00' COMMENT '金额',
`
agent_id` int(11) DEFAULT '0' COMMENT '会员等级ID',
`
start_time` int(10) DEFAULT '0' COMMENT '开始日期',
`
wenti` tinyint(2) DEFAULT '0' COMMENT '问题',
`
daan` varchar(100) DEFAULT '' COMMENT '密保答案',
`
referrer_uid` int(11) DEFAULT '0' COMMENT '推荐人',
`
status` tinyint(1) DEFAULT '1' COMMENT '0禁用 1启用',
`
add_time` int(10) DEFAULT '0' COMMENT '注册日期',
PRIMARY KEY (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=4502 DEFAULT CHARSET=utf8 COMMENT='会员表';
数据量不是很大,会员4500,账户变动记录82000,订单63000
结果:统计推荐人推荐会员总数、提成金额、推荐会员下单总金额。这里会员总数和提成金额是根据会员等级再变动,所以无法用固定比例。
第一次写的sql语句如下:
SELECT t2.referrer_uid,t1.username,t2.count,
(SELECT sum(use_money) from p_account_log where change_type=3 and p_account_log.uid=t1.uid) as use_money,
(SELECT sum(sum_money) from p_order where uid in (select uid from p_user where referrer_uid=t1.uid)) as sum_money
from p_user t1
INNER JOIN (select referrer_uid,count(*) as count from p_user where referrer_uid>0 GROUP BY referrer_uid) t2
on t1.uid=t2.referrer_uid
ORDER BY use_money desc
执行时间9.6S,毫无疑问那个双层子查询拖慢了速度,改变一下:
SELECT t2.referrer_uid,t1.username,t2.count,
(SELECT sum(use_money) from p_account_log where change_type=3 and p_account_log.uid=t1.uid) as use_money,
SUM(t3.sum_money) as sum_money
from p_user t1
INNER JOIN (select referrer_uid,count(*) as count from p_user where referrer_uid>0 GROUP BY referrer_uid) t2
on t1.uid=t2.referrer_uid
INNER JOIN
(SELECT m1.uid,m2.referrer_uid,m2.username,sum(sum_money) as sum_money from p_order m1
INNER JOIN p_user m2 on m1.uid=m2.uid and m2.referrer_uid>0
GROUP BY m1.uid,m2.referrer_uid) t3
on t3.referrer_uid=t2.referrer_uid
group by t2.referrer_uid
ORDER BY use_money desc
执行时间0.2S,啊哦,本来还想着把提成金额也分解出来,看情况不用了。
结论:子查询尽量别滥用!