MySQL:优化查询

Posted

技术标签:

【中文标题】MySQL:优化查询【英文标题】:MySQL: Optimizing queries 【发布时间】:2021-01-09 12:51:43 【问题描述】:

如何以更优化的方式编写此代码?

SELECT week_day
     , SUM(min_0 + min_1 + min_2 + min_3) 
     / (SELECT SUM(min_0 + min_1 + min_2 + min_3)
             FROM Hotel.RegIn) * 100 AS MIN_PERCENTAGE
  FROM Hotel.RegIn 
 WHERE week_day = "Wednesday" 
 GROUP 
    BY week_day;

【问题讨论】:

任何时候你发现自己有枚举列名(上面说 2),你可以确信你的架构设计是次优的 你必须使用单选表达式吗? @Nae 不是真的我只是在寻找另一种方式来编写查询,也许是一种更优化的方式 【参考方案1】:

我会这样写:

SELECT
    "Wednesday",
     100 * SUM((week_day = "Wednesday") * (min_0 + min_1 + min_2 + min_3))
        / SUM(min_0 + min_1 + min_2 + min_3) AS MIN_PERCENTAGE
 FROM Hotel.RegIn
;

或者,如果您可以使用多个语句,则可以使用另一个更简单的过滤器:

SET @var_all_day_total :=
    (SELECT SUM(min_0 + min_1 + min_2 + min_3) FROM Hotel.RegIn) / 100;

SELECT
    week_day,
    SUM(min_0 + min_1 + min_2 + min_3) / @var_all_day_total AS MIN_PERCENTAGE
FROM Hotel.RegIn
-- WHERE week_day = "Wednesday"
GROUP BY
    week_day
;

这个想法通常是不要重复计算相同的值超过一次。

【讨论】:

【参考方案2】:

您应该在FROM 子句中使用派生表。这样子查询只会被评估一次。

SELECT 
  week_day,
  SUM(min_0 + min_1 + min_2 + min_3) / RegInSum.sum_all * 100 AS MIN_PERCENTAGE 
FROM
  Hotel.RegIn,
  (SELECT 
    SUM(min_0 + min_1 + min_2 + min_3) as sum_all 
  FROM
    Hotel.RegIn) as RegInSum 
WHERE week_day = "Wednesday" 
GROUP BY week_day;

请注意,只要将查询限制为一周中的一天,重写查询不会获得任何性能提升,因为在这两种情况下子查询只会被评估一次。

请参阅CTE (Common Table Expressions),了解在较新版本的 mysql 中更易读的派生表语法。

【讨论】:

所以你的意思是说两者在查询优化方面是一样的? @tootiefairy 是的,我想如果你确定你只会在星期三使用你的查询(或者一周中的任意一天,例如在参数中指定),你没有优化您的原始查询。

以上是关于MySQL:优化查询的主要内容,如果未能解决你的问题,请参考以下文章

MySql性能优化查询优化

mysql多条件查询的优化

mysql查询优化器应该怎么使用

MySQL查询优化器工作原理解析

mysql优化之查询优化

mysql查询优化策略