优化删除

时间:2014-09-24 07:10:00

标签: sql performance postgresql optimization

我有一个导入系统,用于更新表中现有行的列。由于UPDATE需要时间,我将其更改为DELETE和BULK INSERT。

这是我的数据库设置代码段

Table: ParameterDefinition
Columns: Id, Name, Other Cols

Table: ParameterValue
Columns: Id, CustId, ParameterDefId, Value

我从我的XML源获取与ParamterDefinition.Name相关联的值,因此要导入我首先删除所有现有的ParamterValue,其中包含XML中传递的所有ParamterDefinition.Name,最后从XML中批量插入所有值。这是我的查询

DELETE FROM ParameterValue WHERE CustId = ? AND ParameterDefId IN (?,?...?);

对于1000个客户,上述DELETE语句被调用1000次,现在非常耗时,大约64秒。

有没有更好的方法来处理1000个客户的DELETE?

谢谢,

Sheeju

2 个答案:

答案 0 :(得分:1)

为批量插入创建临时表(ParameterValue_Import)。对此表执行批量插入,然后根据导入的数据更新/插入/删除。

INSERT INTO .. SELECT .. WHERE NOT EXISTS ( .. )表示新行

UPDATE .. FROM了解更新

DELETE FROM WHERE NOT EXISTS ( .. )删除

批量操作比独立操作具有更好的性能。大多数DBMS旨在处理基于集合的操作而不是基于记录的操作。

修改

要基于仅引用一条记录的WHERE子句删除或更新一条记录,DBMS应该执行全表扫描(如果where条件没有索引)或执行索引查找。只有在成功识别记​​录之后,DBMS才会继续执行原始请求(更新或删除)。根据表中的记录数和/或索引的大小/深度,这可能非常昂贵。对批处理中的每个命令都执行此过程。总结总成本,可能比基于另一个表更新/删除记录更重要。 (特别是如果操作更新/删除目标表中的几乎所有记录。)

当您尝试一次删除/更新多个记录时(例如,基于另一个表),DBMS可以仅使用一个表扫描/索引查找进行查找,并在处理您的请求时进行逻辑连接。

纯粹更新记录的成本在每种情况下都是相同的,只是查找的总成本可能会有很大差异。

此外删除然后插入记录来更新它可能需要更多资源:当您删除记录时,所有相关索引都将是更新,当您插入新记录时,索引将再次更新,同时更新记录,只应更新那些与更新列相关的索引(索引更新应该只进行一次)。

答案 1 :(得分:1)

我给出了@Pred

给出的上述想法的确切语法

批量插入后,假设您有“ParamterValue_Import”中的数据

要插入“ParamterValue_Import”中不在“ParamterValue”中的记录

INSERT INTO ParameterValue (
  CustId, ParameterDefId, Value
)
SELECT
  CustId, ParameterDefId, Value
FROM
  ParameterValue_Import
WHERE
  NOT EXISTS (
    SELECT null
    FROM ParameterValue
    WHERE ParameterValue.CustId = ParameterValue_Import.CustId
);

更新“ParamterValue”中的记录,这些记录也在“ParamterValue_Import”中

UPDATE
  ParameterValue
SET
  Value = ParameterValue_Import.Value
FROM
  ParameterValue_Import
WHERE
  ParameterValue.ParameterDefId = ParameterValue_Import.ParameterDefId
  AND ParameterValue.CustId = ParameterValue_Import.CustId;