V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zhaoxixiangban
V2EX  ›  程序员

[sql 优化] 麻烦大佬看下这段 sql 怎么优化能快点

  •  
  •   zhaoxixiangban · 2020-05-11 10:39:31 +08:00 · 2650 次点击
    这是一个创建于 1440 天前的主题,其中的信息可能已经有所发展或是发生改变。
    CREATE TABLE `fx_share` (
    `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
    `share_id` varchar(36) NOT NULL COMMENT '分享 ID',
    `share_channel_id` varchar(10) DEFAULT NULL COMMENT '分享渠道 ID',
    `aim_id` varchar(36) NOT NULL COMMENT '分享目标 ID',
    `share_url` varchar(255) DEFAULT NULL COMMENT '分享的链接',
    `share_user_id` varchar(36) NOT NULL COMMENT '分享发起人(导购)',
    `share_title` varchar(255) DEFAULT NULL COMMENT '分享的标题(预留字段)',
    `share_extra` varchar(255) DEFAULT NULL COMMENT '分享的参数(预留字段)',
    `watch_count` int(11) DEFAULT NULL COMMENT '浏览次数',
    `create_time` datetime NOT NULL COMMENT '创建时间',
    `update_time` datetime DEFAULT NULL COMMENT '更新时间',
    `deleted` tinyint(1) DEFAULT NULL COMMENT '删除:0 未删除,1 删除',
    `bind_status` varchar(5) DEFAULT 'true' COMMENT '绑定状态 用于顾客和导购绑定(为 0 时可以绑定,为 1 时不可以绑定)',
    PRIMARY KEY (`id`,`share_id`) USING BTREE,
    UNIQUE KEY `unx_shareid` (`share_id`) USING BTREE,
    KEY `idx_userid` (`share_user_id`) USING BTREE,
    KEY `idx_aim` (`aim_id`) USING BTREE,
    KEY `create_time_index` (`create_time`) USING BTREE
    ) ENGINE=InnoDB AUTO_INCREMENT=811316 DEFAULT CHARSET=utf8mb4 COMMENT='分享表';


    EXPLAIN SELECT
    `share_user_id` AS `shoppingGuideId`,
    count( share_user_id ) AS `statisticNum`
    FROM
    fx_share FORCE INDEX(create_time_index)
    WHERE
    create_time > '2020-01-01 00:00:03' AND create_time <'2020-06-28 16:55:03'
    GROUP BY
    `shoppingGuideId`
    23 条回复    2020-05-23 10:47:28 +08:00
    zhaoxixiangban
        1
    zhaoxixiangban  
    OP
       2020-05-11 10:42:23 +08:00
    "id" "1"
    "select_type" "SIMPLE"
    "table" "fx_share"
    "partitions" "range"
    "type" "range"
    "possible_keys" "idx_userid,create_time_index"
    "key" "key_len" "create_time_index"
    "ref" "5"
    "rows" "217959"
    "filtered" "100"
    "Extra" "Using index condition; Using temporary; Using filesort"
    freebird1994
        2
    freebird1994  
       2020-05-11 10:52:31 +08:00
    联合索引咯,share_user_id,create_time 。
    gengz
        3
    gengz  
       2020-05-11 10:58:01 +08:00
    建个索引(share_user_id, create_time)
    purensong
        4
    purensong  
       2020-05-11 11:02:31 +08:00
    我想法是再派生出一列,把 create_time 的日期提取出来作为字段 date,加上索引,先筛选 date 再筛选 create_time
    dongisking
        5
    dongisking  
       2020-05-11 11:14:38 +08:00
    create_time 建索引不好,4F 方案不错
    zhaoxixiangban
        6
    zhaoxixiangban  
    OP
       2020-05-11 11:28:22 +08:00
    @purensong 你是説,增加字段 date copy create_time 字段,然后 [date> '2020-01-01 00:00:03' AND date<'2020-06-28 16:55:03' and create_time > '2020-01-01 00:00:03' AND create_time <'2020-06-28 16:55:03' ] 这样么?
    zhaoxixiangban
        7
    zhaoxixiangban  
    OP
       2020-05-11 11:28:55 +08:00
    @freebird1994 感谢 ,但是建立联合索引没有改善
    zhaoxixiangban
        8
    zhaoxixiangban  
    OP
       2020-05-11 11:29:02 +08:00
    @gengz 感谢 ,但是建立联合索引没有改善
    zhaoxixiangban
        9
    zhaoxixiangban  
    OP
       2020-05-11 11:29:22 +08:00
    @dongisking 嗯 我试试,谢谢
    stevenkang
        10
    stevenkang  
       2020-05-11 11:38:14 +08:00
    建议按粒度定时统计,要用时直接从统计表查。

    12 小时以内的数据,按分钟统计;
    1 周以内的数据,按小时统计;
    一周以上的数据,按天统计;
    zhaoxixiangban
        11
    zhaoxixiangban  
    OP
       2020-05-11 11:46:00 +08:00
    @stevenkang 这个明天就要用,我也是这么想的,空间换时间。但是实现需要点时间,只能先上功能后面优化了。
    goodboy95
        12
    goodboy95  
       2020-05-11 14:04:46 +08:00
    为什么楼上是先 share_user_id 再 create_time 的?这按理说不应该是先筛 create_time,再照 share_user_id 去分组吗?我开始对自己的知识产生怀疑了……
    不过怀疑归怀疑,试一下建立(create_time, share_user_id)的组合索引吧,也算是帮我证明一下我的知识有没有问题了。
    goodboy95
        13
    goodboy95  
       2020-05-11 14:06:14 +08:00
    顺便把 FORCE_INDEX 去掉再看看,建组合索引之后 FORCE_INDEX 容易绊脚
    zhaoxixiangban
        14
    zhaoxixiangban  
    OP
       2020-05-11 14:16:02 +08:00
    @goodboy95 #13 受教了,到 1s 内了。组合索引也有顺序问题,组合索引用 FORCE_INDEX 会有影响
    jsq2627
        15
    jsq2627  
       2020-05-11 14:26:43 +08:00
    zhaoxixiangban
        16
    zhaoxixiangban  
    OP
       2020-05-11 14:45:07 +08:00
    @jsq2627 #15 可以的 赞!
    sansanhehe
        17
    sansanhehe  
       2020-05-11 16:37:51 +08:00
    @zhaoxixiangban 所以你最终是用的(create_time, share_user_id)索引,还是(share_user_id, create_time)索引?有没有用 force index ?可以分享一下吗?
    goodboy95
        18
    goodboy95  
       2020-05-11 17:19:02 +08:00
    @zhaoxixiangban 好吧,把范围查询的情况给忘了……确实先 share_user_id 才对……
    zhaoxixiangban
        19
    zhaoxixiangban  
    OP
       2020-05-11 17:24:47 +08:00
    @sansanhehe #17 (share_user_id, create_time) 没有用 force index 参考 15 楼
    kimchan
        20
    kimchan  
       2020-05-12 14:39:46 +08:00
    @zhaoxixiangban #19 想问下, 15 楼和 2 楼 3 楼有区别吗.. 因为我看你前面说的建立联合索引没有改善. 看的有点懵
    zhaoxixiangban
        21
    zhaoxixiangban  
    OP
       2020-05-13 13:40:40 +08:00
    @kimchan #20 前面我没有去掉 “FORCE_INDEX”
    947030638
        22
    947030638  
       2020-05-14 08:34:51 +08:00 via iPhone
    联合索引不是有顺序吗?先执行 where 再执行 group,createtime 比 shareuserid 先执行,所以为啥是 share_user_id, create_time
    zhaoxixiangban
        23
    zhaoxixiangban  
    OP
       2020-05-23 10:47:28 +08:00
    @947030638 #22 这个我也没有想通,很费解,但是(share_user_id, create_time) 确实很快。18 楼说有范围查询的情况,没想通。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2581 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 75ms · UTC 04:20 · PVG 12:20 · LAX 21:20 · JFK 00:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.