付费解决mysql sum 多字段统计慢的问题

最近遇见一个sum 统计特别慢的问题。

大概有13个字段需要sum 和一个count

数据五六万就要去到5秒

微ID amu-ajin 欢迎大佬联系我

佣金:500起


CREATE TABLE "order_orders" (
  "id" bigint unsigned NOT NULL AUTO_INCREMENT,
  "oid" char(20) COLLATE utf8mb4_unicode_ci NOT NULL,
  "user_id" bigint unsigned NOT NULL,
  "username" varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL,
  "nickname" varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL,
  "quantity" bigint unsigned NOT NULL DEFAULT '1',
  "amount" decimal(20,4) NOT NULL,
  "consumption" decimal(20,4) NOT NULL DEFAULT '0.0000',
  "pay_amount" decimal(20,4) NOT NULL DEFAULT '0.0000',
  "discount" decimal(20,4) NOT NULL DEFAULT '0.0000',
  "order_at_day" date NOT NULL,
  "created_at" timestamp NULL DEFAULT NULL,
  "updated_at" timestamp NULL DEFAULT NULL,
  PRIMARY KEY ("id"),
  KEY "order_orders_oid_index" ("oid"),
  KEY "order_orders_user_id_index" ("user_id"),
  KEY "order_orders_order_at_day_index" ("order_at_day")
);
DB::table('order_orders')
    ->select(
        [
            'username',
            'nickname',
            DB::raw('count(quantity) as quantity'),
            DB::raw('sum(amount) as amount'),
            DB::raw('sum(consumption) as consumption'),
            DB::raw('sum(pay_amount) as pay_amount'),
            DB::raw('sum(discount) as discount'),

        ]
    )
    ->whereIn('user_id', [1, 2, 3, 5, 8, 11])
    ->whereBetween('order_at_day', $this->request->dateRange)
    ->groupBy(
                'username',
                'nickname',
        )
    ->cursor();
Ryan
Mumujin
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 25

我是讨论 MySQL

数据五六万,是指 order_orders 表的数量嘛?还是 user_id IN (1, 2, 3, 5, 8, 11) 的数量。。

  1. order_orders_user_id_index 索引改成 (user_id, order_at_day) 应该能提速?(这个 order_at_day 在哪儿。。)
  2. 为嘛不能 GROUP BY user_id 呢?
2年前 评论
Mumujin (楼主) 2年前
wxf666 (作者) 2年前
wxf666 (作者) 2年前
Mumujin (楼主) 2年前
Mumujin (楼主) 2年前
wxf666 (作者) 2年前
Mumujin (楼主) 2年前
wxf666 (作者) 2年前
Mumujin (楼主) 2年前
wxf666 (作者) 2年前
Mumujin (楼主) 2年前
Mumujin (楼主) 2年前
wxf666 (作者) 2年前

explain 分析,贴出下索引的命中情况。

2年前 评论
Mumujin (楼主) 2年前

把cursor改成get试试多久🌚

2年前 评论

用云服务么,可以用云服务来解这种题,另外OLTP、OLAP混用了么,分析类建议走OLAP就很好解了,就是稍微花点钱,不用那么折腾。

2年前 评论
wxf666 2年前
wikimo (作者) 2年前

group by治标不治本,修改代码吧!新增一张表按维度聚合。

2年前 评论

为啥我的expain结果跟你的不一样

EXPLAIN SELECT
    `username`,
    `nickname`,
    count(quantity) AS quantity,
    sum(amount) AS amount,
    sum(consumption) AS consumption,
    sum(pay_amount) AS pay_amount,
    sum(discount) AS discount
FROM
    `order_orders`
WHERE
    `user_id` IN (1, 2, 3, 5, 8, 11)
AND `order_at_day` BETWEEN '2000-01-01'
AND '2022-09-26'
GROUP BY
    `username`,
    `nickname`

2年前 评论

做个缓存,定时每分钟更新一下就行了,统计数据没必要实时,或者同步个列存储库,统计数据从列存储走,也算是近实时

2年前 评论

建多一个表来存统计数据。定时同步过来

2年前 评论

先in 查出来在自己foreach 处理数据试试呢?

2年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!