我有 3 个订单表。
1-) orders
orderID ⎜odate ⎜ fullname ⎜address ⎜ ordersum ⎜ status_id
2-) order_products
id ⎜orderID ⎜count⎜ psum ⎜cost
3-) order_sum
orderID ⎜shipping ⎜tax ⎜coupon ⎜ discount
对于下面的订单,我按日期获得“折扣/订单值(value)/产品总和/税总和”。但是查询 20000 条记录需要 12 秒。我该如何优化它?
SELECT
DATE(o.odate) AS ODate,
COUNT(o.orderID) AS OTotal,
(
SELECT
SUM(op.psum)
FROM
order_products op
INNER JOIN orders oo ON oo.orderID = op.orderID
WHERE
DATE(oo.odate) = DATE(o.odate)
AND oo.status_id NOT IN (24, 26, 27, 28, 29)
) AS ProductSum,
SUM(os.shipping) / 118 * 100 AS Shipping,
SUM(os.tax) AS Tax,
SUM(o.ordersum) AS allPayments,
SUM(os.coupon) AS CouponDiscount,
SUM(os.discount) AS Discount,
(
SUM(o.ordersum) / COUNT(DISTINCT o.orderID)
) AS BasketAVG
FROM
orders o
JOIN order_sum os ON os.orderID = o.orderID
WHERE
o.status_id NOT IN (24, 26, 27, 28, 29)
AND o.odate BETWEEN '2014-12-01'
AND '2014-12-30'
GROUP BY
DATE(o.odate)
ORDER BY
o.odate ASC;
扩展:
+----+--------------------+-------+--------+-----------------+-----------+---------+-----------------------------+-------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+-------+--------+-----------------+-----------+---------+-----------------------------+-------+----------------------------------------------+
| 1 | PRIMARY | o | ALL | PRIMARY,orders | NULL | NULL | NULL | 10645 | Using where; Using temporary; Using filesort |
| 1 | PRIMARY | os | eq_ref | PRIMARY,ordersum| PRIMARY | 4 | cikolat_system.o.orderID | 1 | |
| 2 | DEPENDENT SUBQUERY | oo | ALL | PRIMARY,orders | NULL | NULL | NULL | 10645 | Using where |
| 2 | DEPENDENT SUBQUERY | op | ref | oproducts2 | oproducts2| 5 | cikolat_system.oo.orderID | 1 | Using where |
+----+--------------------+-------+--------+-----------------+-----------+---------+-----------------------------+-------+----------------------------------------------+
SQLFiddle:http://sqlfiddle.com/#!2/81c921/1
最佳答案
我建议您放弃 SELECT 列表中的相关子查询,并使用连接操作到内联 View 。我会这样写查询:
SELECT DATE(o.odate) AS ODate
, COUNT(o.orderID) AS OTotal
, ps.ProductSum AS ProductSum
, SUM(os.shipping) / 118 * 100 AS Shipping
, SUM(os.tax) AS Tax
, SUM(o.ordersum) AS allPayments
, SUM(os.coupon) AS CouponDiscount
, SUM(os.discount) AS Discount
, SUM(o.ordersum)
/ COUNT(DISTINCT o.orderID) AS BasketAVG
FROM orders o
JOIN order_sum os
ON os.orderID = o.orderID
LEFT
JOIN ( SELECT op.orderID
, SUM(op.psum) AS ProductSum
FROM order_products op
GROUP BY op.orderID
) ps
ON ps.orderID = o.orderID
WHERE o.status_id NOT IN (24, 26, 27, 28, 29)
AND o.odate BETWEEN '2014-12-01' AND '2014-12-30'
GROUP BY DATE(o.odate)
ORDER BY DATE(o.odate) ASC
解释输出将显示派生表; MySQL 5.5 及更早版本将取消索引。
如果从 orders 表中检索到的行是整个表的一小部分,则 orders 表上的适当索引可能允许 MySQL 使用索引范围扫描操作:
... ON orders (odate, status)
而且,如果这是表中行的一小部分,那么内联 View 查询中的 JOIN 操作将生成一个小得多的派生表,这可能会提高性能。在内联 View 查询中对 orders 表重复谓词,例如:
LEFT
JOIN ( SELECT op.orderID
, SUM(op.psum) AS ProductSum
FROM order_products op
JOIN orders oo
ON oo.orderID = op.orderID
WHERE oo.status_id NOT IN (24, 26, 27, 28, 29)
AND oo.odate BETWEEN '2014-12-01' AND '2014-12-30'
GROUP BY op.orderID
) ps
此外,order_products 上的覆盖索引将允许 MySQL 完全从索引满足 View 查询(EXPLAIN 将显示“使用索引”)
... ON order_products (orderID, psum)
(如果 odate 列的数据类型是 DATE,那么 DATE() 包装函数是不必要的,MySQL 可以避免“使用文件排序”。如果数据类型是 DATETIME 或 TIMESTAMP 数据类型,这解释了 DATE() 包装函数的使用。请注意,odate 列上的谓词将返回值介于每月第一天午夜到每月 30 日午夜之间的行。通常,我们只返回整日,并避免排除 30 日午夜。
AND o.odate >= '2014-12-01 00:00:00'
AND o.odate < '2014-12-30 00:00:00'
(我在文字值中添加时间部分是不必要的;添加只是为了说明在与日期时间或时间戳进行比较时考虑时间部分的想法。)
关于mysql - SQL 优化 - 3 个表 - 多个 SUM - 20k 记录 - 12 秒,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27707214/
文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co
需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc
目录第1题连续问题分析:解法:第2题分组问题分析:解法:第3题间隔连续问题分析:解法:第4题打折日期交叉问题分析:解法:第5题同时在线问题分析:解法:第1题连续问题如下数据为蚂蚁森林中用户领取的减少碳排放量iddtlowcarbon10012021-12-1212310022021-12-124510012021-12-134310012021-12-134510012021-12-132310022021-12-144510012021-12-1423010022021-12-154510012021-12-1523.......找出连续3天及以上减少碳排放量在100以上的用户分析:遇到这类
我正在尝试查询我的Rails数据库(Postgres)中的购买表,我想查询时间范围。例如,我想知道在所有日期的下午2点到3点之间进行了多少次购买。此表中有一个created_at列,但我不知道如何在不搜索特定日期的情况下完成此操作。我试过:Purchases.where("created_atBETWEEN?and?",Time.now-1.hour,Time.now)但这最终只会搜索今天与那些时间的日期。 最佳答案 您需要使用PostgreSQL'sdate_part/extractfunction从created_at中提取小时
我看到其他人也遇到过类似的问题,但没有一个解决方案对我有用。0.3.14gem与其他gem文件一起存在。我已经完全按照此处指示完成了所有操作:https://github.com/brianmario/mysql2.我仍然得到以下信息。我不知道为什么安装程序指示它找不到include目录,因为我已经检查过它存在。thread.h文件存在,但不在ruby目录中。相反,它在这里:C:\RailsInstaller\DevKit\lib\perl5\5.8\msys\CORE\我正在运行Windows7并尝试在Aptana3中构建我的Rails项目。我的Ruby是1.9.3。$gemin
我已经开始使用mysql2gem。我试图弄清楚一些基本的事情——其中之一是如何明确地执行事务(对于批处理操作,比如多个INSERT/UPDATE查询)。在旧的ruby-mysql中,这是我的方法:client=Mysql.real_connect(...)inserts=["INSERTINTO...","UPDATE..WHEREid=..",#etc]client.autocommit(false)inserts.eachdo|ins|beginclient.query(ins)rescue#handleerrorsorabortentirelyendendclient.commi
我找到了这样的东西:Rails:Howtolistdatabasetables/objectsusingtheRailsconsole?这一行没问题:ActiveRecord::Base.connection.tables并返回所有表但是ActiveRecord::Base.connection.table_structure("users")产生错误:ActiveRecord::Base.connection.table_structure("projects")我认为table_structure不是Postgres方法。如何列出Postgres数据库的Rails控制台中表中的所有
Ruby中防止SQL注入(inject)的好方法是什么? 最佳答案 直接使用ruby?使用准备好的语句:require'mysql'db=Mysql.new('localhost','user','password','database')statement=db.prepare"SELECT*FROMtableWHEREfield=?"statement.execute'value'statement.fetchstatement.close 关于ruby-防止SQL注入(inject
我正在编写一个Rails应用程序,它将监视某些特定数据库的数据质量。为了做到这一点,我需要能够对这些数据库执行直接SQL查询——这当然与用于驱动Rails应用程序模型的数据库不同。简而言之,这意味着我无法使用通过ActiveRecord基础连接的技巧。我需要连接的数据库在设计时是未知的(即:我不能将它们的详细信息放在database.yaml中)。相反,我有一个模型“database_details”,用户将使用它来输入应用程序将在运行时执行查询的数据库的详细信息。因此与这些数据库的连接实际上是动态的,细节仅在运行时解析。 最佳答案
深度学习12.CNN经典网络VGG16一、简介1.VGG来源2.VGG分类3.不同模型的参数数量4.3x3卷积核的好处5.关于学习率调度6.批归一化二、VGG16层分析1.层划分2.参数展开过程图解3.参数传递示例4.VGG16各层参数数量三、代码分析1.VGG16模型定义2.训练3.测试一、简介1.VGG来源VGG(VisualGeometryGroup)是一个视觉几何组在2014年提出的深度卷积神经网络架构。VGG在2014年ImageNet图像分类竞赛亚军,定位竞赛冠军;VGG网络采用连续的小卷积核(3x3)和池化层构建深度神经网络,网络深度可以达到16层或19层,其中VGG16和VGG