Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 15 additions & 22 deletions v2.1/delete.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ The `DELETE` [statement](sql-statements.html) deletes rows from a table.

{{site.data.alerts.callout_info}}To delete columns, see <a href="drop-column.html"><code>DROP COLUMN</code></a>.{{site.data.alerts.end}}


## Required privileges

The user must have the `DELETE` and `SELECT` [privileges](privileges.html) on the table.
Expand Down Expand Up @@ -54,12 +53,11 @@ Deleting a row does not immediately free up the disk space. This is
due to the fact that CockroachDB retains [the ability to query tables
historically](https://www.cockroachlabs.com/blog/time-travel-queries-select-witty_subtitle-the_future/).

If disk usage is a concern, there are two potential solutions. The
first is to [reduce the time-to-live](configure-replication-zones.html)
(TTL) for the zone, which will cause garbage collection to clean up
deleted rows more frequently. Second, unlike `DELETE`,
[truncate](truncate.html) immediately deletes the entire table, so
consider if you can use `TRUNCATE` instead.
If disk usage is a concern, the solution is to
[reduce the time-to-live](configure-replication-zones.html) (TTL) for
the zone by setting `gc.ttlseconds` to a lower value, which will cause
garbage collection to clean up deleted objects (rows, tables) more
frequently.

## Select performance on deleted rows

Expand All @@ -84,19 +82,9 @@ You can delete all rows from a table by not including a `WHERE` clause in your `
DELETE 7
~~~

This is roughly equivalent to [`TRUNCATE`](truncate.html).

{% include copy-clipboard.html %}
~~~ sql
> TRUNCATE account_details;
~~~
~~~
TRUNCATE
~~~

As you can see, one difference is that `TRUNCATE` does not return the number of rows it deleted.

{{site.data.alerts.callout_info}}The <code>TRUNCATE</code> statement removes all rows from a table by dropping the table and recreating a new table with the same name. This is much more performant than deleting each of the rows. {{site.data.alerts.end}}
{{site.data.alerts.callout_success}}
Unless your table is small (less than 1000 rows), using [`TRUNCATE`][truncate] to delete the contents of a table will be more performant than using `DELETE`.
{{site.data.alerts.end}}

### Delete specific rows

Expand All @@ -120,7 +108,7 @@ In this example, `account_id` is our primary key and we want to delete the row w
+------------+---------+--------------+
~~~

#### Delete rows Using non-unique columns
#### Delete rows using non-unique columns

Deleting rows using non-unique columns removes _every_ row that returns `TRUE` for the `WHERE` clause's `a_expr`. This can easily result in deleting data you didn't intend to.

Expand All @@ -144,6 +132,7 @@ The example statement deleted two rows, which might be unexpected.
To see which rows your statement deleted, include the `RETURNING` clause to retrieve them using the columns you specify.

#### Use all columns

By specifying `*`, you retrieve all columns of the delete rows.

{% include copy-clipboard.html %}
Expand Down Expand Up @@ -195,9 +184,13 @@ When `RETURNING` specific columns, you can change their labels using `AS`.
- [`INSERT`](insert.html)
- [`UPDATE`](update.html)
- [`UPSERT`](upsert.html)
- [`TRUNCATE`](truncate.html)
- [`TRUNCATE`][truncate]
- [`ALTER TABLE`](alter-table.html)
- [`DROP TABLE`](drop-table.html)
- [`DROP DATABASE`](drop-database.html)
- [Other SQL Statements](sql-statements.html)
- [Limiting Query Results](limit-offset.html)

<!-- Reference Links -->

[truncate]: truncate.html
6 changes: 3 additions & 3 deletions v2.1/truncate.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ summary: The TRUNCATE statement deletes all rows from specified tables.
toc: true
---

The `TRUNCATE` [statement](sql-statements.html) deletes all rows from specified tables.
The `TRUNCATE` [statement](sql-statements.html) removes all rows from a table. At a high level, it works by dropping the table and recreating a new table with the same name.

{{site.data.alerts.callout_info}}
`TRUNCATE` removes all rows from a table by dropping the table and recreating a new table with the same name. For large tables, this is much more performant than deleting each of the rows. However, for smaller tables, it's more performant to use a [`DELETE` statement without a `WHERE` clause](delete.html#delete-all-rows).
For smaller tables (with less than 1000 rows), using a [`DELETE` statement without a `WHERE` clause](delete.html#delete-all-rows) will be more performant than using `TRUNCATE`.
{{site.data.alerts.end}}

## Synopsis
Expand Down Expand Up @@ -152,5 +152,5 @@ pq: "customers" is referenced by foreign key from table "orders"

## See also

- [`DELETE](delete.html)
- [`DELETE`](delete.html)
- [Foreign Key constraint](foreign-key.html)
37 changes: 15 additions & 22 deletions v2.2/delete.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ The `DELETE` [statement](sql-statements.html) deletes rows from a table.

{{site.data.alerts.callout_info}}To delete columns, see <a href="drop-column.html"><code>DROP COLUMN</code></a>.{{site.data.alerts.end}}


## Required privileges

The user must have the `DELETE` and `SELECT` [privileges](privileges.html) on the table.
Expand Down Expand Up @@ -54,12 +53,11 @@ Deleting a row does not immediately free up the disk space. This is
due to the fact that CockroachDB retains [the ability to query tables
historically](https://www.cockroachlabs.com/blog/time-travel-queries-select-witty_subtitle-the_future/).

If disk usage is a concern, there are two potential solutions. The
first is to [reduce the time-to-live](configure-replication-zones.html)
(TTL) for the zone, which will cause garbage collection to clean up
deleted rows more frequently. Second, unlike `DELETE`,
[truncate](truncate.html) immediately deletes the entire table, so
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh, I think maybe GH ate my comment. Maybe @vivekmenezes can chime in here, but AFAIK, TRUNCATE doesn't delete the on-disk data any sooner -- it just avoids writing deletes for every row.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh! I think it did eat it. Definitely did not receive this info earlier. Thanks for posting it again @dt

So if I'm reading you right, I have the following statements/questions which I would appreciate your (and/or @vivekmenezes ') input on:

  1. DELETE works by issuing deletes per-row (are these "delete intents" (term?) that are written to each row and later cleaned up during a GC pass? is that why you say they involve a write? if so, makes sense that it would be slower)
  2. TRUNCATE works by marking (?) the entire table all at once for deletion (using same model from Completed draft of start a local cluster #1 above, if accurate)
  3. Because of this, TRUNCATE is faster from the user POV because it writes less to disk, i.e. O(1) (table) instead of O(n) ( # of rows touched) -- though it doesn't actually delete the on-disk data sooner in terms of clock time since that is determined by when GC runs - yes?

If the above are approximately right, my (weak) opinion is that from the user's POV the semantics of TRUNCATE are still best expressed as "TRUNCATE immediately deletes the entire table". But it depends on how much of the machinery of deletion/GC we want to expose in the docs. Our users may really need this info to avoid confusion. Let me know what you think.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we want to says.

  1. Normally, TRUNCATE should be used to delete all the table data, but TRUNCATE is implemented as a schema change which is not transactional. Therefore some data added within a short interval after the TRUNCATE might get deleted by the truncate.
  2. Alternatively, DELETE can be use for transactional deletion of table data, but care must be taken because it will not work on very large tables because of the large transactions are not supported limitation.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My point is that if you want the disk space back, neither TRUNCATE nor DELETE are going to give it to you, but the current text seems to imply that TRUNCATE will which is what I was objecting to. To be fair, it is better than DELETEs in terms of disk space since it doesn't write a tombstone on every row, but it still isn't going to free it up any sooner than the GC time.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks David and Vivek for the info. Sounds like neither statement is useful for reclaiming disk, so we need to remove that bit.

Just pushed a change (also copied below) to reflect that neither statement will give your disk space back (soon), and you must update your GC TTL settings. Let me know what you think.

If disk usage is a concern, the solution is to reduce the time-to-live (TTL) for the zone by setting gc.ttlseconds to a lower value, which will cause garbage collection to clean up deleted objects (rows, tables) more frequently.

consider if you can use `TRUNCATE` instead.
If disk usage is a concern, the solution is to
[reduce the time-to-live](configure-replication-zones.html) (TTL) for
the zone by setting `gc.ttlseconds` to a lower value, which will cause
garbage collection to clean up deleted objects (rows, tables) more
frequently.

## Select performance on deleted rows

Expand All @@ -84,19 +82,9 @@ You can delete all rows from a table by not including a `WHERE` clause in your `
DELETE 7
~~~

This is roughly equivalent to [`TRUNCATE`](truncate.html).

{% include copy-clipboard.html %}
~~~ sql
> TRUNCATE account_details;
~~~
~~~
TRUNCATE
~~~

As you can see, one difference is that `TRUNCATE` does not return the number of rows it deleted.

{{site.data.alerts.callout_info}}The <code>TRUNCATE</code> statement removes all rows from a table by dropping the table and recreating a new table with the same name. This is much more performant than deleting each of the rows. {{site.data.alerts.end}}
{{site.data.alerts.callout_success}}
Unless your table is small (less than 1000 rows), using [`TRUNCATE`][truncate] to delete the contents of a table will be more performant than using `DELETE`.
{{site.data.alerts.end}}

### Delete specific rows

Expand All @@ -120,7 +108,7 @@ In this example, `account_id` is our primary key and we want to delete the row w
+------------+---------+--------------+
~~~

#### Delete rows Using non-unique columns
#### Delete rows using non-unique columns

Deleting rows using non-unique columns removes _every_ row that returns `TRUE` for the `WHERE` clause's `a_expr`. This can easily result in deleting data you didn't intend to.

Expand All @@ -144,6 +132,7 @@ The example statement deleted two rows, which might be unexpected.
To see which rows your statement deleted, include the `RETURNING` clause to retrieve them using the columns you specify.

#### Use all columns

By specifying `*`, you retrieve all columns of the delete rows.

{% include copy-clipboard.html %}
Expand Down Expand Up @@ -195,9 +184,13 @@ When `RETURNING` specific columns, you can change their labels using `AS`.
- [`INSERT`](insert.html)
- [`UPDATE`](update.html)
- [`UPSERT`](upsert.html)
- [`TRUNCATE`](truncate.html)
- [`TRUNCATE`][truncate]
- [`ALTER TABLE`](alter-table.html)
- [`DROP TABLE`](drop-table.html)
- [`DROP DATABASE`](drop-database.html)
- [Other SQL Statements](sql-statements.html)
- [Limiting Query Results](limit-offset.html)

<!-- Reference Links -->

[truncate]: truncate.html
6 changes: 3 additions & 3 deletions v2.2/truncate.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ summary: The TRUNCATE statement deletes all rows from specified tables.
toc: true
---

The `TRUNCATE` [statement](sql-statements.html) deletes all rows from specified tables.
The `TRUNCATE` [statement](sql-statements.html) removes all rows from a table. At a high level, it works by dropping the table and recreating a new table with the same name.

{{site.data.alerts.callout_info}}
`TRUNCATE` removes all rows from a table by dropping the table and recreating a new table with the same name. For large tables, this is much more performant than deleting each of the rows. However, for smaller tables, it's more performant to use a [`DELETE` statement without a `WHERE` clause](delete.html#delete-all-rows).
For smaller tables (with less than 1000 rows), using a [`DELETE` statement without a `WHERE` clause](delete.html#delete-all-rows) will be more performant than using `TRUNCATE`.
{{site.data.alerts.end}}

## Synopsis
Expand Down Expand Up @@ -152,5 +152,5 @@ pq: "customers" is referenced by foreign key from table "orders"

## See also

- [`DELETE](delete.html)
- [`DELETE`](delete.html)
- [Foreign Key constraint](foreign-key.html)