2014-09-24 70 views
0

我有一个进口商系统,它更新表中已有行的列。由于更新需要时间,我将其更改为DELETE和BULK INSERT。优化删除

这里是我的数据库设置片段

Table: ParameterDefinition 
Columns: Id, Name, Other Cols 

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

我从我的XML源关联到ParamterDefinition.Name的值,所以进口我第一次删除所有现有ParamterValue所有的ParamterDefinition.Name在传递XML并最终对XML中的所有值进行批量插入。这里是我的查询

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

为1000个客户以上DELETE语句被称为1000倍,这是非常耗时,现在,大约64秒。

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

谢谢,

Sheeju

+0

用于删除数据库还必须找到记录来对其进行操作。我建议再次检查更新查询,看看它为什么会变慢。 此外,为什么不使用'transaction'来帮助DB不会每次都将更改写入磁盘,而是在您提交时将它们集中在一起。我的2美分。 – Sanjeev 2014-09-24 07:15:12

+0

你给了我们一个假设,即瓶颈是数据库。但是在寻求解决方案之前,您需要确定瓶颈。考虑到你正在通过外键删除记录(这些记录应该被自然地编入索引),我很惊讶它正在让数据库平台去做它的工作。你肯定这不是一个应用程序问题? – rurouni88 2014-09-24 07:21:33

+0

@sanjeev:更新查询需要更多时间,可以说每个客户平均有3个参数值被更新,1个新的参数值然后会导致3000个更新和1000个插入。我已经在使用事务来确保我执行单一提交 – sheeju 2014-09-24 08:14:11

回答

1

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

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

UPDATE .. FROM的更新

DELETE FROM WHERE NOT EXISTS (..)为删除

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

编辑

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

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

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

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

+1

请详细解释一下吗? – sheeju 2014-09-24 09:29:21

+0

这个够了吗? – Pred 2014-09-24 09:42:02

+1

感谢您的详细解释 – sheeju 2014-09-24 11:24:22

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;