通过从多个表条件检索数据来优化 SQL UPDATE 查询

问题描述 投票:0回答:1

我有三张桌子:

  1. dup_IMCS_IMCS_MASTER_API

  2. dup_IMCS_IMCS_MASTER

  3. dup_IMCS_IMCS_MASTER_3PTY 我的目标表是表 1,即 dup_IMCS_IMCS_MASTER_API 源表为 2. dup_IMCS_IMCS_MASTER 和 3. dup_IMCS_IMCS_MASTER_3PTY。 问题陈述如下:

  4. 首先,检查 dup_IMCS_IMCS_MASTER_API 中的 ALIAS_PN 列。如果 ALIAS_PN IS NULL,则数据应来自 dup_IMCS_IMCS_MASTER。在 dup_IMCS_IMCS_MASTER 中,数据应来自 dup_IMCS_IMCS_MASTER_API 中的 DESCRIPTION 列到 SHORT_DESCRIPTION 列。

  5. 如果 ALIAS_PN IS NOT NULL,则数据应来自 dup_IMCS_IMCS_MASTER_3PTY 中的两列。 SHORT_DESC 和 DESC1 。但数据应来自哪一列的条件如下。 数据应主要来自 SHORT_DESC。但如果 dup_IMCS_IMCS_MASTER_3PTY 的 SHORT_DESC 为 NULL,则 dup_IMCS_IMCS_MASTER_3PTY 中的 DESC1 列应分配给 dup_IMCS_IMCS_MASTER_API 中的目标列 SHORT_DESCRIPTION 为此写一个更新 SQL 查询给我。

我想出了下面的 SQL 查询:

-----v1.0
UPDATE AYaramati.dup_IMCS_IMCS_MASTER_API A
SET SHORT_DESCRIPTION = (
  CASE
    WHEN A.ALIAS_PN IS NULL THEN (SELECT DESCRIPTION FROM AYaramati.dup_IMCS_IMCS_MASTER WHERE dup_IMCS_IMCS_MASTER.PN = A.PN)
    ELSE COALESCE((SELECT SHORT_DESC FROM AYaramati.dup_IMCS_IMCS_MASTER_3PTY WHERE dup_IMCS_IMCS_MASTER_3PTY.PN = A.PN), (SELECT DESC1 FROM AYaramati.dup_IMCS_IMCS_MASTER_3PTY WHERE dup_IMCS_IMCS_MASTER_3PTY.PN = A.PN))
  END
);

我进一步优化了查询:

----v1.1
UPDATE AYaramati.dup_IMCS_IMCS_MASTER_API A
SET SHORT_DESCRIPTION = 
  COALESCE(
    (SELECT M.DESCRIPTION FROM AYaramati.dup_IMCS_IMCS_MASTER M WHERE EXISTS (SELECT 1 FROM AYaramati.dup_IMCS_IMCS_MASTER MT WHERE MT.PN = A.PN) AND A.ALIAS_PN IS NULL),
    (SELECT COALESCE(P.SHORT_DESC, P.DESC1) FROM AYaramati.dup_IMCS_IMCS_MASTER_3PTY P WHERE EXISTS (SELECT 1 FROM AYaramati.dup_IMCS_IMCS_MASTER_3PTY PT WHERE PT.PN = A.PN) AND A.ALIAS_PN IS NOT NULL)
  );

当我尝试运行此命令时,更新查询花费了太多时间来运行。这可能是因为源表和目标表都包含超过 50 万条记录。我该如何优化这个查询?查询是否有效?

sql sql-update dml
1个回答
0
投票

通过从多个表中进行条件数据检索来优化 SQL UPDATE 查询时,可以采用多种策略来提高性能。这是分步指南:

  1. 使用正确的索引:确保 JOIN 和 WHERE 子句中使用的所有相关列都正确索引。这有助于数据库引擎快速定位所需的行。

  2. 最小化数据检索:仅从表中检索必要的数据。避免使用 SELECT * 而是指定您需要的确切列。这减少了数据库必须处理的数据量。

  3. 对子查询使用 EXISTS 或 IN :不要使用 JOIN 进行条件数据检索,而是考虑对子查询使用 EXISTS 或 IN 子句。这些有时可以表现得更好,特别是在处理大型数据集时。

  4. 避免嵌套子查询:嵌套子查询会显着降低性能。尽可能尝试将它们重写为 JOIN 或 EXISTS/IN 子句。

  5. 避免重复子查询:如果多次使用同一个子查询,请考虑使用临时表或公用表表达式 (CTE) 来存储子查询的结果,然后连接到它。

  6. 批量更新:批量更新不是逐行更新,而是更高效。您可以使用 UPDATE...JOIN 或 UPDATE 等技术与 CASE 语句来根据特定条件一次更新多行。

  7. 优化 JOINs:确保 JOIN 条件有效并使用适当的连接类型(INNER JOIN、LEFT JOIN 等)。有时重写 JOIN 或将其分解为多个步骤可以提高性能。

  8. 分析执行计划:使用特定于数据库的工具来分析查询的执行计划。这可以帮助识别潜在的瓶颈并提出优化建议。

  9. 考虑非规范化:如果优化查询后性能仍然是一个问题,请考虑通过存储冗余信息来对数据进行非规范化。这可以消除对复杂联接的需求并提高查询性能,尽管它需要在数据完整性和存储空间方面进行权衡。

这里有一个通用示例来说明其中一些概念:

UPDATE table1
SET column1 = (
    SELECT columnX
    FROM table2
    WHERE table1.id = table2.id
)
WHERE EXISTS (
    SELECT 1
    FROM table2
    WHERE table1.id = table2.id
    AND table2.columnY > 100
);

在此示例中,我们根据

column1
中的数据更新
table1
中的
table2
,但仅限于满足特定条件 (
columnY > 100
) 的行。我们使用 EXISTS 子句来检查
table2
中是否存在此类行,而不是直接连接表。这有时会更有效,特别是当子查询返回一个大数据集时。

请记住,这些优化的有效性可能会有所不同,具体取决于您使用的特定数据库系统、数据的大小和结构以及其他因素。测试不同的方法并监控性能以确定适合您情况的最有效策略非常重要。

© www.soinside.com 2019 - 2024. All rights reserved.