此页面包含使用SQL语句从 hubble中删除数据行的说明。
在阅读本页之前,请执行以下操作:
在本页的示例中,我们使用通过命令导入的示例数据。
要删除表中的行,请使用带有WHERE
子句的DELETE
语句,该子句过滤标识要删除的行的列。
在 SQL中,DELETE
语句一般采用以下形式:
DELETE FROM {table} WHERE {filter_column} {comparison_operator} {filter_value}
参数说明:
{table}
是包含要删除的行的表。{filter_column}
是要过滤的列。{comparison_operator}
是一个比较运算符,解析为TRUE
或FALSE
(例如,=
)。{filter_value}
是过滤器的匹配值。以下是删除行时要遵循的一些最佳做法:
DELETE
您执行的语句数量。使用单个语句删除多行比执行多个DELETE
语句删除单个行更有效。WHERE
子句。DELETE
如果没有WHERE
指定子句,hubble将删除指定表中的所有行。TRUNCATE
语句而不是DELETE
语句。DELETE
语句时,请确保将 SQL执行函数包装在重试循环中,以处理可能在争用下发生的事务错误。删除在非唯一列上过滤的行
假设要删除一定范围编号的历史数据,empno
要删除表中介于两个值(1-1000)之间的所有行。
delete from emp where empno BETWEEN 1 AND 1000;
// 'db' is an open database connection
tsOne := 1
tsTwo := 1000
if _, err := db.Exec("delete from emp where empno BETWEEN $1 AND $2", tsOne, tsTwo); err != nil {
return err
}
return nil
// ds is an org.postgresql.ds.PGSimpleDataSource
int tsOne = 1;
int tsTwo = 1000;
try (Connection connection = ds.getConnection()) {
PreparedStatement p = connection.prepareStatement("delete from emp where empno BETWEEN ? AND ?");
p.setInt(1, tsOne);
p.setInt(2, tsTwo);
p.executeUpdate();
} catch (SQLException e) {
System.out.printf("sql state = [%s]\ncause = [%s]\nmessage = [%s]\n", e.getSQLState(), e.getCause(),
e.getMessage());
}
# conn is a psycopg2 connection
tsOne = 1
tsTwo = 1000
with conn.cursor() as cur:
cur.execute(
"delete from emp where empno BETWEEN %s AND %s", (tsOne, tsTwo))
删除在唯一列上过滤的行
假设要删除特定编号的历史数据。
delete from emp where empno in (1001,7369,3256);
// 'db' is an open database connection
codeOne := 1001
codeTwo := 7369
codeThree := 3256
if _, err := db.Exec("delete from emp where empno in ($1, $2, $3)", codeOne, codeTwo, codeThree); err != nil {
return err
}
return nil
// ds is an org.postgresql.ds.PGSimpleDataSource
int codeOne = 1001;
int codeTwo = 7369;
int codeThree = 3256;
try (Connection connection = ds.getConnection()) {
PreparedStatement p = connection.prepareStatement("delete from emp where empno in (?, ?, ?)");
p.setInt(1, codeOne);
p.setInt(2, codeTwo);
p.setInt(3, codeThree);
p.executeUpdate();
} catch (SQLException e) {
System.out.printf("sql state = [%s]\ncause = [%s]\nmessage = [%s]\n", e.getSQLState(), e.getCause(),
e.getMessage());
}
# conn is a psycopg2 connection
codeOne = 1001
codeTwo = 7369
codeThree = 3256
with conn.cursor() as cur:
cur.execute("delete from emp where empno in (%s, %s, %s)", (codeOne, codeTwo, codeThree)),
由于hubble在后台工作的方式,从数据库中删除数据不会立即减少磁盘使用量。相反,记录被标记为'已删除'并由后台垃圾收集进程异步处理。默认情况下,此过程每25小时运行一次。
以便有足够的时间使用AS OF SYSTEM TIME
, 垃圾收集间隔由gc.ttlseconds
设置控制。
上述的实际意义是:
DELETE
按顺序发出多条语句,每条语句都删除大量数据,那么后续的每条DELETE
语句都会运行得更慢。为了保持迭代DELETE
查询的性能,我们建议采用以下方法之一:
WHERE
子句以仅过滤尚未标记为删除的行。例如,请参阅索引过滤器上的批量删除。SELECT
语句返回尚未删除的行的主键值。标记为删除的行将不会被返回。然后,在较小的批量大小上使用嵌套DELETE
循环,过滤主键值。有关示例,请参阅对非索引列进行批量删除。DELETE
循环,您可以更改区域配置并将其更改gc.ttlseconds
为5分钟即值为300,然后在DELETE
每个GC
间隔运行一次语句。磁盘的释放为表级别的,通过以下命令,对需要经常大批量删除的表进行设置。比如:
alter table test_a CONFIGURE ZONE using gc.ttlseconds = 1800;
通过监控页面,会发现半个小时候后,仪表盘的存储情况,存储空间得以释放,且删除的数据量越大释放情况会很明显。