我有一个导入系统,用于更新表中现有行的列。由于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
答案 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;