一次查询优化...

2020-10-15 15:03:38 +08:00
 raymanr

部门同事来找我说现在用的几个存储过程(离职同事写的)查询太慢了, 要几个小时才能出结果, 于是我打开后看到了如此的内容...

我也不是说有什么优越感, 但是这槽点也太大了...

以下是部分片段, 该存储过程总计 900 行, 类似的计算部分大概有四百行多, 剩余部分全是字符串拼接

该同事还留下了另外几个存储过程等待修改, 看到五百行往上的满篇 left join, with 套 with

十几个表 left join, 还是 on a.col1 >= b.col2 and a.col2 < b.col2 这种连接

现在只想摸鱼


-- GMV
SET
    @start_gmv = (
        SELECT
            SUM(`客户付款总金额(¥)`)
        FROM
            `历史订单明细`
        WHERE
            `测算日期范围` = start_estimate_date
            AND `部门` LIKE CONCAT('%', @department, '%')
            AND `经营团队` LIKE CONCAT('%', @management_team, '%')
            AND `组别` LIKE CONCAT('%', @groups, '%')
    );

SET
    @end_gmv = (
        SELECT
            SUM(`客户付款总金额(¥)`)
        FROM
            `历史订单明细`
        WHERE
            `测算日期范围` = end_estimate_date
            AND `部门` LIKE CONCAT('%', @department, '%')
            AND `经营团队` LIKE CONCAT('%', @management_team, '%')
            AND `组别` LIKE CONCAT('%', @groups, '%')
    );

-- 订单量
SET
    @start_order = (
        SELECT
            COUNT(*)
        FROM
            `历史订单明细`
        WHERE
            `测算日期范围` = start_estimate_date
            AND `部门` LIKE CONCAT('%', @department, '%')
            AND `经营团队` LIKE CONCAT('%', @management_team, '%')
            AND `组别` LIKE CONCAT('%', @groups, '%')
    );

SET
    @end_order = (
        SELECT
            COUNT(*)
        FROM
            `历史订单明细`
        WHERE
            `测算日期范围` = end_estimate_date
            AND `部门` LIKE CONCAT('%', @department, '%')
            AND `经营团队` LIKE CONCAT('%', @management_team, '%')
            AND `组别` LIKE CONCAT('%', @groups, '%')
    );

-- 产品销量
SET
    @start_sale = (
        SELECT
            SUM(`产品销量`)
        FROM
            `历史订单明细`
        WHERE
            `测算日期范围` = start_estimate_date
            AND `部门` LIKE CONCAT('%', @department, '%')
            AND `经营团队` LIKE CONCAT('%', @management_team, '%')
            AND `组别` LIKE CONCAT('%', @groups, '%')
    );

SET
    @end_sale = (
        SELECT
            SUM(`产品销量`)
        FROM
            `历史订单明细`
        WHERE
            `测算日期范围` = end_estimate_date
            AND `部门` LIKE CONCAT('%', @department, '%')
            AND `经营团队` LIKE CONCAT('%', @management_team, '%')
            AND `组别` LIKE CONCAT('%', @groups, '%')
    );

-- 客单价
SET
    @start_atv = (
        SELECT
            SUM(`客户付款总金额(¥)`) / COUNT(*)
        FROM
            `历史订单明细`
        WHERE
            `测算日期范围` = start_estimate_date
            AND `部门` LIKE CONCAT('%', @department, '%')
            AND `经营团队` LIKE CONCAT('%', @management_team, '%')
            AND `组别` LIKE CONCAT('%', @groups, '%')
    );

SET
    @end_atv = (
        SELECT
            SUM(`客户付款总金额(¥)`) / COUNT(*)
        FROM
            `历史订单明细`
        WHERE
            `测算日期范围` = end_estimate_date
            AND `部门` LIKE CONCAT('%', @department, '%')
            AND `经营团队` LIKE CONCAT('%', @management_team, '%')
            AND `组别` LIKE CONCAT('%', @groups, '%')
    );

-- 产品成本占比
...
2202 次点击
所在节点    程序员
16 条回复
sxfscool
2020-10-15 15:17:20 +08:00
中文列表是不是槽点[捂脸]
sxfscool
2020-10-15 15:17:40 +08:00
列名,打错了
weizhen199
2020-10-15 15:21:48 +08:00
我也不想看。。加索引加 hint 完事。
或者让他们改 java 做
ahmcsxcc
2020-10-15 15:22:21 +08:00
什么数据库说下啊
raymanr
2020-10-15 15:23:59 +08:00
@sxfscool
不是, 中文名其实我倒觉得还好, 比英文名还容易看懂意思点

WHERE 部分的 LIKE 运算符会进行全表扫描, 速度本来就很慢,

于是每查询一个变量就需要进行一次全表扫描,

可每次查询的都是同一张表同一个条件
raymanr
2020-10-15 15:28:17 +08:00
@weizhen199
人都跑了, 现在这球提到我这来改了, 唉, 这么复杂的存储过程, 我花一两个个月来改不算过分吧
Mithril
2020-10-15 15:32:26 +08:00
@raymanr 可以的,不过你也别改了,马上 2077 就要 release 了。你要一个月的时间,花一礼拜重写了它,剩下的时间玩玩 2077 不香吗?
xuanbg
2020-10-15 16:14:31 +08:00
唯一的槽点是 like,你可以改成= ‘xxid’,让程序先用可以模糊查询的下拉列表 like 查到并选中 id,再查询数据,这样就可以走索引了。
xuanbg
2020-10-15 16:18:16 +08:00
@xuanbg 譬如部门参数,就可以通过输入「业务」查询到业务 1 部、业务 2 部……,然后选中业务 1 部得到业务 1 部的 id,再用这个 id 来查询。
Rimifon
2020-10-15 16:19:33 +08:00
这个是不是应该先 select 到一个临时表,然后从临时表去做统计。like 语句改成 charindex 会不会好一些。
raymanr
2020-10-15 16:22:09 +08:00
@xuanbg
算了, 本来就是非正规的业务, 数据部门的破事, 一个大表没主键没维度表, 主要也是这个 like 循环套循环的全表扫描一百多遍槽点太大了, 实际上查询需要用到的数据也就二三十万行, 跑了几个小时说出去真的是太丢人了
zoharSoul
2020-10-15 16:48:59 +08:00
@sxfscool 专有领域中文列名挺好的.
很多东西不好翻译.
lasuar
2020-10-15 17:28:19 +08:00
为什么那么多人喜欢写存储过程
zouzou0208
2020-10-16 08:21:49 +08:00
建议重写。
no1xsyzy
2020-10-16 11:54:19 +08:00
@zoharSoul 然而不是中文专有领域,这些中文单词都是英文强行翻译过来的,找到原本的英文术语就行
@xuanbg 但是我挺喜欢我用的系统就这么 concat 两个 % 上去当作模糊搜索的,有必要的话我自己也可以手写几个 % 进去更模糊地搜索(
raymanr
2020-10-16 17:58:24 +08:00
@lasuar
我恨存储过程, 改这个破东西时候心里已经骂了提出用存储过程来解决和写这个垃圾存储过程的人五千万遍了

尤其是今天快改完时候发现最后几行的一个没见过的函数, 打开该函数发现又是一千行的时候

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/715246

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX