表结构:
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,啊哦,本来还想着把提成金额也分解出来,看情况不用了。
结论:子查询尽量别滥用!