SQL - INSERT IF NOT EXIST,检查是否相同或更新

时间:2013-12-04 20:15:57

标签: java sql sqlite

我希望DBMS在进行大量插入操作时帮助我提高速度。

今天我在Java中执行INSERT查询,如果数据已经在数据库中,则捕获异常。 我得到的例外是:

SQLite Exception : [19] DB[1] exec() columns recorddate, recordtime are not unique.

如果我收到异常,我会使用主键SELECT Query执行recorddate, recordtime,并将结果与​​我尝试在Java中插入的数据进行比较。如果它是相同的,我继续下一个插入,否则我评估数据并决定保存什么,并可能做一个更新。

这个过程需要时间,我想加快速度。

我想过INSERT IF NOT EXIST但是如果有任何数据具有相同的主键,这只是忽略插入,我是对的吗?我想在忽略插入之前确保它是完全相同的数据。

我很感激有关如何加快速度的建议。

我正在使用Java处理大量数据以插入SQLite数据库(SQLite v.3.7.10)。作为Java和SQLite之间的连接,我使用的是sqlite4java(http://code.google.com/p/sqlite4java/

3 个答案:

答案 0 :(得分:0)

我认为让dbms处理更多逻辑的速度更快,至少不是普通的SQL,只要我能想到没有"创建或更新"那里。

当处理大量条目时,延迟通常是一个重要问题,特别是对于通过网络访问的dbs,所以至少在这种情况下,您希望尽可能使用大规模操作。即使提供,"创建或更新"而不是选择和更新或插入(如果是偶数)只会延迟一半。

我意识到这不是你要求的,但我会尝试以不同的方式进行优化,处理数据块,将所有数据选择到地图中,然后在创建,更新和忽略中对输入进行分区。这种方式忽略几乎是免费的,并且保证在内存中进行进一步的查找。不太可能,dbms可以明显更快。

如果不确定这是否适合您,那么分析开销时间应该会有所帮助。

答案 1 :(得分:0)

所有插入并更新到事务中。在SQL中,这将写成如下。

BEGIN;
INSERT OR REPLACE INTO Table(Col1,Col2) VALUES(Val1,Val2); 
COMMIT;

这里有两点需要注意:在调用COMMIT之前,不会将数据库分页和提交写入磁盘,从而加快查询 ;第二件事是INSERT OR REPLACE语法,它准确地为UNIQUEPRIMARY KEY字段提供了所需的内容。

大多数数据库包装器都有一种用于管理事务的特殊语法。您当然可以执行查询BEGIN,然后执行插入和更新,然后执行COMMIT。阅读数据库包装器文档。

您可以做的另一件事是切换到Write-Ahead Logging。在数据库上只运行一次以下命令。

PRAGMA journal_mode = wal;

答案 2 :(得分:0)

如果没有进一步的信息,我会:

BEGIN;
UPDATE table SET othervalues=... WHERE recorddate=... AND recordtime=...;
INSERT OR IGNORE INTO table(recorddate, recordtime, ...) VALUES(...);
COMMIT;

UPDATE将更新所有现有行,因WHERE子句而忽略不存在。

然后

INSERT会添加新行,因为IGNORE而忽略了现有行。