我有一个600万行的SQLite表。从表格中删除所有数据的最佳方法是什么?
做DELETE FROM TABLE很慢;
删除表,然后重新创建它似乎更快。
我用它来进行数据库导入。
会丢掉表是一种更好的方法,或者有没有办法快速删除所有数据?
我有一个600万行的SQLite表。从表格中删除所有数据的最佳方法是什么?
做DELETE FROM TABLE很慢;
删除表,然后重新创建它似乎更快。
我用它来进行数据库导入。
会丢掉表是一种更好的方法,或者有没有办法快速删除所有数据?
一般来说,DROP TABLE将是一个未记录的事务。 DELETE FROM将需要临时日志记录记录,直到DELETE语句完成。
我不认为SQLite的实现TRUNCATE
但如果这样做,可能会比DELETE
TRUNCATE TABLE更好的性能是快了很多。
除了从甲骨文网站的以下解释了原因:
“删除”进行正常的DML。也就是说,它们对行进行锁定,产生重做(大量),并且它们需要UNDO表空间中的段。仔细删除块清除记录。如果发生错误,可以发出回滚以在提交之前恢复记录。删除不会放弃段空间,因此删除所有记录的表格将保留其所有原始块。
截断是DDL,从某种意义上说,作弊。截断将表格的高水位标记移回零。不采用行级锁,不生成重做或回滚。从表中取消初始化的所有扩展数据块(如果您将MINEXTENTS设置为1以外的任何值,那么将保留该数据块的范围而不仅仅是初始值)。通过重新定位高位标记,可以防止读取任何表格数据,因此它们与删除效果相同,但没有任何开销。只有一个小问题:截断是一个DDL命令,所以如果你决定犯了错误,你就不能回滚它。 (当然,你不能有选择地截断 - 不允许使用“WHERE”子句,这与删除不同)。
通过重置高水位标记,truncate防止读取任何表数据,因此它们与删除具有相同的效果,但没有开销。但是,必须牢记截断的一个方面。因为Truncate是DDL,所以它在它作用之前发出一个COMMIT,然后在另一个COMMIT之后发出,所以不可能回滚事务。
请注意,默认情况下,即使未指定DROP STORAGE,TRUNCATE也会丢弃存储。
一些瓶颈对不起,没看到乌尔使用SQLite。我认为这个帖子回答你的问题。 http://stackoverflow.com/questions/4280041/sqlite-truncate-a-table-if-exists – DeanOC
这是一个非常准确的回答一个问题,用户也没有问。用户正在与SQLite合作,这是Oracle的一个非常不同的动物。 –
@Larry勒斯蒂格 - 是的,我不知道,TRUNCATE不可用。我的错。也就是说,为什么TRUNCATE速度更快的要点与Oracle以外的其他实施TRUNCATE的DB相关,例如, SQL Server。 – DeanOC
你有没有尝试过'TRUNCATE TABLE'? –
SQLite没有一个'TRUNCATE',但它应该做一个截断优化时,有没有'WHERE' – Lamak
@Lamak我在MySQL知道DELETE没有WHERE相当于截断 –