mysql - 嵌套多个 select 语句的性能影响

标签 mysql sql sql-server tsql

我正在编写一个查询,该查询需要在 SQL Server 和 MySQL 上运行,涉及执行非常冗长的计算。如果我将所有内容都写在一个查询中,则会涉及大量复制和粘贴以及冗余且难以维护的代码。因此,我编写了一个更紧凑的版本,基本上如下所示:

SELECT calc3...
FROM 
(
  SELECT calc2...
  FROM
  (
    SELECT calc1...
    FROM original_table
  )
)

是否有任何理由相信这会导致性能不佳?例如每个选择是否都会导致 SQL Server 或 MySQL 在幕后创建一个额外的临时表,从而使执行时间增加两倍?

计算不涉及查询任何其他表,只是将列值相加、将整数映射到字符串等。

我只能访问一个小型测试数据集,因此无法运行它并为其计时,因为使用小型数据集运行只需不到一秒的时间。而且我没有权限查看执行计划。所以我不知道如何去验证这在性能方面不会是一场灾难。 (我可以在生产数据库的副本上测试它,但这是一个漫长而痛苦的过程)

编辑:需要明确的是,我将在生产数据库的副本上对此进行测试,我只是希望在这样做之前看看这里是否存在任何明显的陷阱,因为这样做将是一个耗时的过程。例如如果我多次调用 ALTER TABLE,有人可能会指出 ALTER TABLE 对于 MySQL 来说可能非常慢,因此建议将其全部合并到一个调用中或完全避免它

编辑2:

相关表格如下所示:

pid     Name
1       Value1
1       Value2
1       Value4
2       Value2
2       Value5
3
4       Value1
4       Value1
4       Value4

它需要转换成这样的表格:

pid     Output
1       'Many values'
2       'Two and five'
3       'Missing'
4       'Values 1 and 4'

其中“输出”列中的值基于给定 pid 在第一个表的“名称”列中的值。不幸的是,不可能通过连接名称值或类似的东西来派生这些值,它们相当特殊,并且都需要单独定义。

我的代码经过一些简化,如下所示:

SELECT pid,
CASE
    WHEN TotalValues > 3 THEN 'Many values'
    WHEN TotalValues = 2 AND Value2 = 5 AND Value5 = 1 THEN 'Two and five'
    WHEN TotalValues = 2 AND Value1 = 1 AND Value4 = 1 THEN 'Values 1 and 4'
    WHEN TotalValues = 1 AND Value1 = 1 THEN 'Only value 1'
    When TotalValues = 0 THEN 'Missing' 
    -- About a dozen more of these combinations
END as OutputValue
FROM
(
    SELECT *, Value1 + Value7 as TotalValues
    FROM
    (
        SELECT distinct p.pId
        COALESCE(MAX(CASE WHEN rc.Name = 'Value1' THEN 1 ELSE 0 END),0) as Value1,
        -- more of these that I'm omitting for concision
        COALESCE(MAX(CASE WHEN rc.Name = 'Value7' THEN 1 ELSE 0 END),0) as Value7,
        FROM primary_table AS p 
        LEFT JOIN rc on rc.code=p.code
        WHERE p.desiredRecords = TRUE
        GROUP BY p.pid
    ) t1
) t2

编辑3:

在 SQLYog 中运行 MySQL 查询分析器的结果

MySQL explain results

最佳答案

MySQL 有实现子查询的倾向。对于较新的版本,它并不总是这样做。但出于这个原因,普遍倾向于避免不必要的子查询。

SQL Server 和其他数据库的优化技术要复杂得多。我不知道 SQL Server 中有任何东西会刺激子查询的具体化。如果查看复杂 SQL 查询的执行计划,您将很难找出子查询在哪里。所以,在大多数数据库中,我不会担心它。

CTE 是另一回事 - 你不会问它们,但它们是自然的后续产物。有些数据库从未实现 CTE。我认为有些人总是会实现 CTE。有些人有时会实现它们。为此,您需要对您使用的数据库和版本保持敏感。

关于mysql - 嵌套多个 select 语句的性能影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58941445/

相关文章:

php - 如何使登录页面 PHP 与 Session 一起工作。

sql - Oracle SQL 中最小值但不为 NULL

php/mysql : get data from one table, 转换并插入另一个表

sql - 使用随机名称更新 SQL Server 表

使用分号和撇号的 SQL 崩溃

MySQL查询优化——索引

mysql - 使用 DISTINCT 时发生了什么?

mysql - 创建数据库时,CHARACTER SET 和 COLLATE 中的 default 做了什么?

sql-server - 有没有办法根据变量将 WHERE 子句中的比较设置为 IS NULL 或 IS NOT NULL

用于查看性能缓慢的 MySQL 查询