TRUNCATE

使用 "TRUNCATE命令删除表格中的所有行。 这与 DELETE 命令的效果相同,但对于大型表格来说,比 "DELETE命令更快。

您可以在事务或存储过程中使用 "TRUNCATE,在一个原子单元中对数据进行其他相关更改。 当您以这种方式使用 "TRUNCATE时:
  • 截断事务可以回滚,在这种情况下,表的存储和内容保持不变。
  • 该表被锁定,在截断事务提交或回滚之前,不允许其他会话或事务同时访问该表(包括 "SELECT命令)。 回滚可能是 "ROLLBACK命令或事务执行失败的结果。
  • 如果截断事务访问其他表,发生死锁的可能性就会增加。 您可以在截断事务开始时发出 "LOCK TABLE <tablename> IN ACCESS EXCLUSIVE MODE来避免这个问题。 有关该命令的使用指南,请参阅LOCK TABLE
  • TRUNCATE TABLE比用 "DELETE FROM <table>删除所有行要快得多,而且也不需要后续的 "GROOM TABLE来回收空间。 但它确实会带来一个小风险,即试图修改和截断同一个表的并发事务可能会看到以下信息ERROR: Cannot truncate table because of concurrent insert or update.通过使用 "LOCK TABLE命令,以及让截断一个或多个表的事务保持激活状态的时间不超过实现目标所需的时间,可以最大限度地降低风险。

NPS支持在针对截断表的并发事务中使用 "SELECTs。 只有当没有在截断提交之前开始的活动并发事务时,才会释放被截断表的磁盘存储空间。 如果在提交截断时没有并发事务,则会在提交后几秒钟释放存储。 在 "TRUNCATE提交之前开始的未结事务仍然可以看到 "TRUNCATE提交之前表格中的记录。

除 "SELECT外,修改被截断表的其他操作必须等待截断事务提交或回滚。

如果系统经常有并发会话针对截断的表进行选择,请注意 "TRUNCATE命令会将表行计数统计重置为零。 重置有利于对表格进行更新的后续查询的规划估算。 重置 "TRUNCATE的行数统计会影响并发事务的现有查询。 如果新的行数统计与 "TRUNCATE之前的行数差别很大,则并发查询的运行时间可能会更长,原因是规划器对旧查询的估计不准确。

如果希望保留表的统计信息,以便于飞行中查询,可以配置系统保留 "TRUNCATE之前的表统计信息和行数。 要保留统计数据,可以将数据库变量 concurrent_truncate_zero_stats 设为 false。 该设置会导致系统始终保留表统计信息,而表统计信息会随着表中插入新行而增加,从而导致查询估计问题,延长运行时间。 更改默认行为

  1. 以 nz 用户账户登录NPS系统。
  2. 使用任何文本编辑器打开 "/nz/data/postgresql.conf文件。 编辑 "postgresql.conf时请谨慎。 它包含Netezza Performance Server系统运行的重要配置参数。
  3. 查找文件中的 concurrent_truncate_zero_stats 定义,确保该定义尚未出现和/或被注释掉。 如果找到条目,请确保 concurrent_truncate_zero_stats=false 且未注释。 如果找不到条目,请在文件中添加 concurrent_truncate_zero_stats=false。
  4. 保存并关闭 postgresql.conf 文件。
  5. 使用 "nzstop和 "nzstart命令停止并重新启动NPS软件。

还可以使用 "set concurrent_truncate_zero_stats to <value>命令在个别NPS数据库会话中设置(或重置)concurrent_truncate_zero_stats 变量。 例如,可以在会话级别设置变量,以获得不同表的不同行为。 从同一个表截断数据的不同会话应使用一致的变量设置,以获得一致的行为。

注意:以下是关于在重复截断和重新加载的表中使用 "GENERATE STATISTICS的做法:
  • 不要在 "TRUNCATE(或调用 "TRUNCATE的事务提交后)之后添加 "GENERATE STATISTICS
  • 理想情况下,"GENERATE STATISTICS应在重新加载数据后运行,然后再进行查询。 如果将 concurrent_truncate_zero_stats 设置为 false,这一点尤为重要。 对于大型 Performance Server 表来说,这也是一种很好的通用做法,因为某些统计信息(如列值的 "分散性")在加载时不会自动收集。
  • 如果 "GENERATE STATISTICS 目前没有在每次重载后运行,而且更改现有工作流以添加该命令过于困难,那么在 concurrent_truncate_zero_stats 为假的情况下,应在后台作业中定期运行 "GENERATE STATISTICS。 选择一个工作频率,使上次 "GENERATE STATISTICS后的截断和重载次数不超过四或五次。

语法

截断空表的语法:
TRUNCATE [ TABLE ] <name>

输入

TRUNCATE 命令的输入如下
表 1. TRUNCATE 输入
输入 描述
<name> 要截断的表格名称。

输出

TRUNCATE 命令的输出结果如下:
表 2. TRUNCATE 输出
输出 描述
TRUNCATE TABLE 该命令已成功。

特权

您必须是管理员用户、表所有者、数据库或模式所有者,或者您的账户必须拥有表或表对象类的 Truncate 权限。

用途

以下是使用示例。
  • 删除表 "bigtable中的所有记录:
    MYDB.SCH1(USER)=> TRUNCATE  bigtable;
  • 用新数据替换表格 "mytable的内容:
    BEGIN;
    TRUNCATE TABLE mytable;
    INSERT INTO mytable SELECT …;
    COMMIT;