使用过Oracle的都知道,Truncate操作由于不需要写redo日志,因此,在性能上会比delete操作更高效,但在实际使用过程中,有时会发现delete比truncate速度更快。以下介绍下二者的机制,让大家对二者有清晰的了解。

一、大数据量删除操作

1、数据准备

创建两张没有索引的大表:t1 , t2 ,每张表的数据量接近 350W

test=# create table t2 as select * from t1;
SELECT 3461120

2、测试Delete操作

test=# checkpoint;
CHECKPOINT test=# select pg_current_wal_lsn();
pg_current_wal_lsn
--------------------
0/92DB1FC8
(1 row) test=# select relname,relfilenode from sys_class where relname='t1';
relname | relfilenode
---------+-------------
t1 | 16575
(1 row) test=# delete from t1;
DELETE 3461120
Time: 4771.554 ms (00:04.772) test=# select pg_current_wal_lsn();
pg_current_wal_lsn
--------------------
0/C87A2EC0
(1 row) test=# select pg_wal_lsn_diff('0/C87A2EC0','0/92DB1FC8');
pg_wal_lsn_diff
-----------------
899616504
(1 row)

test=# checkpoint;
CHECKPOINT

test=# select relname,relfilenode from sys_class where relname='t1';
relname | relfilenode
---------+-------------
t1 | 16575
(1 row)

结论:Delete 操作产生了近900M的日志;数据文件的relfilenode 不变。

3、测试Truncate操作

test=# checkpoint;
CHECKPOINT test=# select relname,relfilenode from sys_class where relname='t2';
relname | relfilenode
---------+-------------
t2 | 16581
(1 row) test=# select pg_current_wal_lsn();
pg_current_wal_lsn
--------------------
0/CAA7C678
(1 row) test=# truncate table t2;
TRUNCATE TABLE
Time: 84.124 ms test=# select pg_current_wal_lsn();
pg_current_wal_lsn
--------------------
0/CAA82D40
(1 row) Time: 0.327 ms
test=# select relname,relfilenode from sys_class where relname='t2';
relname | relfilenode
---------+-------------
t2 | 16587
(1 row) Time: 0.491 ms
test=# select pg_wal_lsn_diff('0/CAA82D40','0/CAA7C678');
pg_wal_lsn_diff
-----------------
26312
(1 row) Time: 1.239 ms

结论:Truncate 操作基本不产生redo;relfilenode 会变化,这是由于truncate操作相当于新建了个文件。

三、小数据量删除操作比较

1、比较一:数据未写回磁盘前,进行truncate

test=# declare
test-# v_sql text;
test-# begin
test-# for i in 1..1000 loop
test-# drop table if exists t1;
test-# create table t1 as select * from pg_class;
test-# delete from t1;
test-# end loop;
test-# end;
test-# /
ANONYMOUS BLOCK
Time: 7173.891 ms (00:07.174) test=# declare
test-# v_sql text;
test-# begin
test-# for i in 1..1000 loop
test-# drop table if exists t1;
test-# create table t1 as select * from pg_class;
test-# truncate t1;
test-# end loop;
test-# end;
test-# /
ANONYMOUS BLOCK
Time: 7477.366 ms (00:07.477)

结论:truncate 似乎更慢。从操作系统IO看,二者的IO 相差不大。

可能原因:truncate 在操作系统层面的操作实际删除旧文件,新建新文件。当调用操作系统命令删除旧文件时,需要将数据先写回文件,才能删除。而本例中,实际从create table 到truncate 时间很短,数据还未写回文件。

2、测试二:先建表,在删除数据

declare
v_sql text;
begin
for i in 1..1000 loop
v_sql = 'drop table if exists t'||i;
execute immediate v_sql;
v_sql = 'create table t'||i||' as select * from pg_class';
execute immediate v_sql;
end loop;
end; checkpoint; declare
v_sql text;
begin
for i in 1..1000 loop
v_sql = 'delete from t'||i;
execute immediate v_sql;
end loop;
end;
/
ANONYMOUS BLOCK
Time: 3412.780 ms (00:03.413) declare
v_sql text;
begin
for i in 1..1000 loop
v_sql = 'truncate t'||i;
execute immediate v_sql;
end loop;
end;
/
ANONYMOUS BLOCK
Time: 1268.753 ms (00:01.269)

结论:先建表,再checkpoint ,将数据写回数据文件。然后,再比较Delete 和 Truncate 操作,可以看到即使小表,truncate 操作也快很多。

KingbaseES Truncate 与 Delete 机制比较的更多相关文章

  1. sql中 truncate 、delete与drop区别

    相同点: 1.truncate和不带where子句的delete.以及drop都会删除表内的数据. 2.drop.truncate都是DDL语句(数据定义语言),执行后会自动提交. 不同点: 1. t ...

  2. truncate 、delete与drop区别

    原博文地址:http://www.cnblogs.com/8765h/archive/2011/11/25/2374167.html 相同点: 1.truncate和不带where子句的delete. ...

  3. sql语句中----删除表数据drop、truncate和delete的用法

    sql语句中----删除表数据drop.truncate和delete的用法 --drop drop table  tb   --tb表示数据表的名字,下同 删除内容和定义,释放空间.简单来说就是把整 ...

  4. [转]mysql drop、truncate和delete比较

    一.drop table tb drop将表格直接删除,没有办法找回. 立刻释放磁盘空间 ,不管是 Innodb和MyISAM . 二.truncate (table) tb 该命令可以清空一个表里的 ...

  5. truncate与delete的区别

    TRUNCATE TABLE 在功能上与不带 WHERE 子句的 DELETE 语句相同:二者均删除表中的全部行.但 TRUNCATE TABLE 比 DELETE 速度快,且使用的系统和事务日志资源 ...

  6. sql之truncate 、delete与drop区别

    sql之truncate .delete与drop区别相同点:truncate 和不带 where 子句的 delete,以及 drop 一定会删除表内的数据不同点:1. truncate 和 del ...

  7. 删除表数据drop、truncate和delete的用法

    说到删除表数据的关键字,大家记得最多的可能就是delete了 然而我们做数据库开发,读取数据库数据.对另外的两兄弟用得就比较少了 现在来介绍另外两个兄弟,都是删除表数据的,其实也是很容易理解的 老大- ...

  8. sql server 中删除表中数据truncate和delete的区别(转载自.net学习网)

    我们都知道truncate table可以用来删除整个表的内容,它与delete后面不跟where条件的效果是一样.但除此之外,我们还清楚它们之间有其它的区别吗?本章我们将一起讨论truncate与d ...

  9. TRUNCATE,DORP,DELETE

    TRUNCATE,DORP,DELETE 相同点: truncate和不带where子句的delete, 以及drop都会删除表内的数据 不同点: 1. truncate和 delete只删除数据不删 ...

随机推荐

  1. Docker组成原理

    目录 Docker引擎 OCI容器标准 镜像 启动流程 本文是阅读<深入浅出Docker>的相关学习笔记 起初简单的以为Docker和容器是一种东西,后来才发现Docker是实现了Linu ...

  2. ms08-067漏洞复现

    一.环境说明 kali linux 靶机是 XP (xp启动445) 二.nmap扫描主机存在的漏洞 root@kali:~# nmap --script smb-vuln* 192.168.244. ...

  3. bat实现删除BCUnrar.dll实现无限使用

    删除项目:计算机\HKEY_CURRENT_USER\Software\Scooter Software\Beyond Compare 4下的CacheId 项可以实现Beyond Compare 4 ...

  4. 如何手动解析vue单文件并预览?

    开头 笔者之前的文章里介绍过一个代码在线编辑预览工具的实现(传送门:快速搭建一个代码在线编辑预览工具),实现了css.html.js的编辑,但是对于demo场景来说,vue单文件也是一个比较好的代码组 ...

  5. Java中JSON字符串和对象的互转

    对象转换成json字符串: JSONObject.toJSONString(switchmes) JSON字符串转换成对象: Switchmes switchmes=(Switchmes) JSONO ...

  6. Failed to Setup IP tables: Unable to enable SKIP DNAT rule: (iptables failed: iptables --wait -t nat -I DOCKER -i br-b1938128a963

    报错信息:Failed to Setup IP tables: Unable to enable SKIP DNAT rule:  (iptables failed: iptables --wait ...

  7. ReentrantLock 公平锁源码 第1篇

    ReentrantLock 1 这篇还是接着ReentrantLock的公平锁,没看过第0篇的可以先去看上一篇https://www.cnblogs.com/sunankang/p/16456342. ...

  8. P1087 FBI树 [2004普及]

    这是个正常的.很简单的分治,然后我成功地将这个题搞成了一个贼难搞的东西 还是说一下我那个非常麻烦的思路: 1. 建树 2. 后序遍历 然后就在建树的过程中死循环了,然后还一堆毛病 看了一个AC代码,该 ...

  9. 6 zookeeper实现分布式锁

    zookeeper实现分布式锁 仓库地址:https://gitee.com/J_look/ssm-zookeeper/blob/master/README.md 锁:我们在多线程中接触过,作用就是让 ...

  10. led跑马灯(模糊时钟ambiguous color,非法字符 non printable character,寄存器初值,计数器计数注意事项)

    1.设计定义 让8个led以100ns的速度循环闪烁. 2.设计输入 循环闪烁,还是周期问题,用时钟驱动,所以需要一个时钟信号clk.再给一个复位输入reset,八个输出led信号. 每100ns只有 ...