统计推荐人总数、下单金额的sql优化

表结构:

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

时间: 2024-10-15 19:38:28

统计推荐人总数、下单金额的sql优化的相关文章

oracle count 百万级 分页查询记要总数、总条数优化

oracle count 百万级 分页查询记录总数.总条数优化 oracle count 百万级 查询记录总数.总条数优化 最近做一个项目时,做分页时,发现分页查询速度很慢,分页我做的是两次查询,一次是查询总数,一次是查询分页结果 /** 查询总记录数 **/ SELECT COUNT(id) FROM USER order by id /** 查询结果集 **/ select * from ( select row_.*, rownum rownum_ from ( select id , u

oracle sql优化

第一掌 避免对列的操作 任何对列的操作都可能导致全表扫描,这里所谓的操作包括数据库函数.计算表达式等等,查询时要尽可能将操作移至等式的右边,甚至去掉函数. 例1:下列SQL条件语句中的列都建有恰当的索引,但30万行数据情况下执行速度却非常慢: select * from record where  substrb(CardNo,1,4)='5378'(13秒) select * from record where  amount/30< 1000(11秒) select * from recor

MS Sql优化(转自网络)

MS SQL Server查询优化方法查询速度慢的原因很多,常见如下几种 1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷) 2.I/O吞吐量小,形成了瓶颈效应. 3.没有创建计算列导致查询不优化. 4.内存不足 5.网络速度慢 6.查询出的数据量过大(可以采用多次查询,其他的方法降低数据量) 7.锁或者死锁(这也是查询慢最常见的问题,是程序设计的缺陷) 8.sp_lock,sp_who,活动的用户查看,原因是读写竞争资源. 9.返回了不必要的行和列 10.查询语句不好,没

浅谈sql优化

问题的发现:      菜鸟D在工作的时候发现项目的sql语句很怪,例如 : select a.L_ZTBH, a.D_RQ, a.VC_BKDM, (select t.vc_name from tbkxx t where t.vc_code = a.vc_bkdm) vc_name, a.VC_BZ, a.L_SCLB, a.EN_ZS, a."ROWID", s."ROWID",--冗余列 decode(nvl(a.l_cjsl, 0), 0, 0, round

SQL优化的一些总结

http://www.taobaodba.com/html/851_sql%E4%BC%98%E5%8C%96%E7%9A%84%E4%B8%80%E4%BA%9B%E6%80%BB%E7%BB%93.html SQL的优化是DBA日常工作中不可缺少的一部分,记得在学生时期,曾经在ITPUB上看到一篇帖子,当时楼主在介绍SQL优化的时候,用一个公式来讲解他在做sql优化的时候遵循的原则: T=S/V(T代表时间,S代表路程,V代表速度) S指SQL所需访问的资源总量,V指SQL单位时间所能访问的

MySQL5.6 如何优化慢查询的SQL语句 -- SQL优化

上篇:MySQL5.6 如何优化慢查询的SQL语句 -- 慢日志介绍 在实际的日志分析中,通常慢日志的log数量不少,同时相同的查询被记录的条数也会很多,这里就需要如何从慢日志查询中找到最有问题,最需要优化的日志.在这方面,有很多分析工具,最基本的分析工具就是MySQL自带的mysqldumpslow,mysqldumpslow(Perl脚本)的输出示例: [[email protected] bin]# ./mysqldumpslow -s t -t 1 /usr/local/mysql/da

好记性不如烂笔头之Oracle SQL优化(2)

*sql优化基于oracle11gR2读书笔记* 三.Oracle里的Cursor Oracle中的Cursor是Oracle数据库中SQL解析和执行的载体,是c语言的一种数据结构(oracle是用c写的). Oracle数据库中的Cursor分为两种:一种是Shared Cursor,另外一种是Session Cursor. 1.Shared Cursor 先来了解一下什么是库缓存.库缓存对象. 我们知道Oracle中有一个全局内存区域SGA,而SGA又可以分为java池.大池.共享池.空池等

SQL优化思路大全

一.百万级数据库优化方案 1.对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如: select id from t where num is null 最好不要给数据库留NULL,尽可能的使用 NOT NULL填充数据库. 备注.描述.评论之类的可以设置为 NULL,其他的,最好不要使用NULL. 不要以为 NULL 不需要空间,

oracle 11g亿级复杂SQL优化一例(数量级性能提升)

自从16年之后,因为工作原因,项目中就没有再使用oracle了,最近最近支持一个项目,又要开始负责这块事情了.最近在跑性能测试,配置全部调好之后,不少sql还存在性能低下的问题,主要涉及执行计划的不合理,以及相关pga隐含参数的优化.可能因为几年不接触的原因,略微有些生疏需要review了.这里以最近优化过的某个比较典型的例子为例(这里只讲思路.因为涉及到核心机密,不给出最终结果,16C [email protected]/45GB内存/fio 85/15 iops 8500/1500 配置,优