我正在编写一个查询,该查询需要在 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 有实现子查询的倾向。对于较新的版本,它并不总是这样做。但出于这个原因,普遍倾向于避免不必要的子查询。
SQL Server 和其他数据库的优化技术要复杂得多。我不知道 SQL Server 中有任何东西会刺激子查询的具体化。如果查看复杂 SQL 查询的执行计划,您将很难找出子查询在哪里。所以,在大多数数据库中,我不会担心它。
CTE 是另一回事 - 你不会问它们,但它们是自然的后续产物。有些数据库从未实现 CTE。我认为有些人总是会实现 CTE。有些人有时会实现它们。为此,您需要对您使用的数据库和版本保持敏感。
关于mysql - 嵌套多个 select 语句的性能影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58941445/