admin

MySQL多个子查询与整个查询

sql

我想知道从MySQL数据库获取数据的哪种方法具有更好的性能特征。

在一个主查询中使用子查询:

SELECT
(SELECT SUM(`number`) FROM `table`) as `number_sum`,
(SELECT MAX(`number`) FROM `table`) as `number_max`,
(SELECT MIN(`number`) FROM `table`) as `number_min`

或者,3个不同的SELECT语句检索相同的数据。

提前致谢!


阅读 163

收藏
2021-06-07

共1个答案

admin

由于这三个聚合来自具有相同WHERE条件的同一张表,因此您无需进行子选择。所有这三个聚合都在相同的行分组上进行操作(未GROUP BY指定,因此整个表为一行),因此它们都可以SELECT直接存在于列表中。

SELECT
  SUM(number) AS number_sum,
  MAX(number) AS number_max,
  MIN(number) AS number_min
FROM `table`

如果任何聚合需要基于不同的条件WHERE,那么您将在子句中进行过滤,那么您将需要为不同的条件使用子选择,或者进行笛卡尔联接。LEFT JOIN对于仅返回一行的聚合,此子选择和以下方法应等效,在性能方面:

SELECT
  /* Unique filtering condition - must be done in a subselect */
  (SELECT SUM(number) FROM `table` WHERE `somecolumn` = `somevalue`) AS number_sum,
  MAX(number) AS number_max,
  MIN(number) AS number_min
FROM `table`

或等同于上面的查询,您可以LEFT JOIN针对
不带ON子句_的子查询。仅当您知道子查询将仅返回一行时,才应执行此操作。否则,您将得到笛卡尔乘积-连接一侧返回的行数 _乘以 另一侧返回的行数。

这是方便,如果你需要用一组返回几列WHERE条款及有几列一组不同的WHERE条件,但只有 一个
从每个边行JOIN。在这种情况下,与使用相同子句JOIN进行 两个子 选择相比,它应该更快WHERE

这应该更快。

SELECT
  /* this one has two aggregates sharing a WHERE condition */
  subq.number_sum_filtered,
  subq.number_max_filtered,
  /* ...and two aggregates on the main table with no WHERE clause filtering */
  MAX(`table`.number) AS number_max,
  MIN(`table`.number) AS number_min
FROM
  `table`
  LEFT JOIN (
    SELECT 
       SUM(number) AS number_sum_filtered,
       MAX(number) AS number_max_filtered
    FROM `table`
    WHERE `somecolumn = `somevalue`
  ) subq /* No ON clause here since there's no common column to join on... */

比这个…

SELECT
  /* Two different subselects each over the same filtered set */
  (SELECT SUM(number) FROM `table` WHERE `somecolumn` = `somevalue`) AS number_sum_filtered,
  (SELECT MAX(number) FROM `table` WHERE `somecolumn` = `somevalue`) AS number_max_filtered,
  MAX(`table`.number) AS number_max,
  MIN(`table`.number) AS number_min
FROM
  `table`
2021-06-07