Files
lancedb/docs/web/sql/dql/dedupe.mdx
T
Jack YeandClaude Sonnet 5 de95ed3f6d docs: overhaul curation, feature engineering, security and deployment guides (#4748)
A broad documentation pass across the areas LanceDB Enterprise and
Embedded
diverge on most:

**Data Curation** -- GPU Function execution, Slurm scheduling (and what
Slurm is, for readers new to it), blob late materialization as its own
page, joins, aggregation/profiling, sampling, near-duplicate detection,
chunking, distributed shuffle, and IVF-partition clustering.

**Feature Engineering** -- computed columns and materialized views,
restructured to lead with the Function-based path and show the SQL form
side by side with Python throughout; a single Auto Refresh page instead
of
duplicating scheduling details on every refresh page; adaptive
execution;
checkpointing; GPU and Slurm placement for refresh workers; a Training
Cache page for the PyTorch data loader's automatic cache benefit.

**Security & Governance** -- an Audit Log reference (schema, access,
grants), Secrets promoted to an ordinary catalog object with their own
SQL
DDL and a vending/rotation guide, and privilege-table fixes verified
against the authorization source.

**Deployment & Maintenance** -- Horizontal Scaling and OpenTelemetry
moved
into a real Deployment area; Automated Cleanup folded into Intelligent
Auto-Maintenance (every other maintenance decision already lived there);
RTE Compaction and Advanced Conflict Resolution documented in depth.

**Landing page** -- the Enterprise feature comparison table reorganized
(several redundant or stale rows removed, several new areas added), and
the
"why Enterprise" bullets replaced with ones tied to a concrete page
(Performance, Scale, Fault tolerance, Multicloud deployment, Simplify
operations) instead of vague promises.

Plus a full pass addressing lancedb-gatekeeper's review: a real
test-safety
bug (a quickstart test could silently overwrite and delete a
deployment's
own `frames` table), a fabricated SQL statement with no backing
implementation, an actual dedup-guarantee bug in `take_row_ids`, and
dozens
of documentation-accuracy fixes verified against source rather than
taken
on faith -- each either fixed, or left with an explicit note on why it
needs a feature or deployment owner's sign-off instead of being guessed
at.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_018PXMCbRH6i5w47TsjeEUMT

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-11-03 16:17:24 -08:00

107 lines
3.6 KiB
Plaintext

---
title: "DEDUPE"
sidebarTitle: "DEDUPE"
description: "The dedupe() table function: one representative row per near-duplicate group, scanned over the index."
icon: layer-group
keywords: ["dedupe", "vector_dedup", "sql", "deduplication", "near-duplicate", "table function"]
availability:
embedded: unavailable
enterprise: available
---
`dedupe` scans a vector column's [index](/indexing/vector-index) partitions
for rows closer than a distance threshold, resolves the overlapping pairs it
finds into duplicate groups, and returns one representative row per group --
without a full pairwise scan or a shuffle. See
[`duplicate_pairs`](/sql/dql/duplicate-pairs) to inspect the pairs themselves
before committing to this resolution.
<CodeGroup>
```sql SQL icon="database"
SELECT * FROM dedupe(
<table>,
<vector_column>,
distance_threshold => <float>
[, resolution => 'connected_components' | 'direct_representative']
)
```
</CodeGroup>
<CodeGroup>
```sql SQL icon="database"
SELECT * FROM dedupe(
'frames',
'vec',
distance_threshold => 0.02
)
```
</CodeGroup>
<Note>
Earlier releases spelled this `vector_dedup`; that name is rejected on
current deployments.
</Note>
## Input {#input}
| Argument | Type | Required | Meaning |
| --- | --- | --- | --- |
| table name | string literal | yes | the table to scan |
| vector column | string literal | yes | the indexed vector column to compare |
| `distance_threshold` | float | yes | maximum distance for a pair to count as close |
| `resolution` | `'connected_components'` (default) \| `'direct_representative'` | no | how overlapping pairs group together -- see [Resolution](#resolution) |
`dedupe` always scans every partition and returns original rows -- sampling
a subset of partitions and `id_column` are pair-query-only options, accepted
by [`duplicate_pairs`](/sql/dql/duplicate-pairs#input) but refused here.
## Output {#output}
One row per duplicate group, **in the table's own schema** -- every column of
`<table>`, including a BlobV2 column, comes through unchanged on the
representative row Lance selected for that group. Unlike
[`duplicate_pairs`](/sql/dql/duplicate-pairs#output), there is no fixed
`dedupe`-specific schema to document: the output schema is the source
table's schema.
Because the result is already shaped like the table, it composes directly
into a new table or a materialized view:
<CodeGroup>
```sql SQL icon="database"
CREATE MATERIALIZED VIEW frames_deduped AS
SELECT * FROM dedupe(
'frames',
'vec',
distance_threshold => 0.02
)
```
</CodeGroup>
## Resolution {#resolution}
`resolution` chooses how overlapping pairs group together:
| `resolution` value | How pairs group |
| --- | --- |
| `connected_components` (default) | groups transitively: if a~b and b~c are both close, all three resolve together |
| `direct_representative` | only pairs within the threshold of each other resolve together |
## Estimating on a sample first {#sampling}
`dedupe` itself always scans every partition. To estimate a duplicate rate
on a large table before committing to a full scan, sample partitions with
[`duplicate_pairs`](/sql/dql/duplicate-pairs#sampling) instead, which
accepts `selection`, `count` and `seed` for exactly this.
## What to read next {#next}
<CardGroup cols={2}>
<Card title="DUPLICATE_PAIRS" icon="clone" href="/sql/dql/duplicate-pairs">
Inspect the close pairs themselves instead of the resolved groups.
</Card>
<Card title="Deduplicate near-duplicates" icon="copy" href="/curation/dedupe">
When to reach for this instead of exact-key deduplication.
</Card>
</CardGroup>