Skip to content

perf: allow V1 incremental path to skip config change metadata queries#1403

Open
moomindani wants to merge 2 commits intodatabricks:mainfrom
moomindani:perf/v1-incremental-skip-config-queries
Open

perf: allow V1 incremental path to skip config change metadata queries#1403
moomindani wants to merge 2 commits intodatabricks:mainfrom
moomindani:perf/v1-incremental-skip-config-queries

Conversation

@moomindani
Copy link
Copy Markdown

Resolves #1402

Description

The V1 incremental materialization path calls adapter.get_relation_config() unconditionally during every incremental merge run. This triggers 8 sequential metadata queries against information_schema and system tables — even when none of the related features (tags, constraints, column masks) are in use.

The V2 path already uses process_config_changes(), which respects the incremental_apply_config_changes config flag. This PR replaces the V1 inline code with the same macro, bringing V1 in line with V2.

Change:

  • Remove inline config change detection (3 lines) and application (19 lines) from V1 incremental path
  • Replace with single {{ process_config_changes(target_relation) }} call

Queries eliminated when incremental_apply_config_changes: false:

  1. SELECT ... FROM system.information_schema.table_tags
  2. SELECT ... FROM system.information_schema.column_tags
  3. SELECT ... FROM information_schema.columns (NOT NULL constraints)
  4. SELECT ... FROM information_schema.key_column_usage (PRIMARY KEY)
  5. SELECT ... FROM information_schema.key_column_usage (FOREIGN KEY)
  6. SELECT ... FROM system.information_schema.column_masks
  7. SHOW TBLPROPERTIES
  8. DESCRIBE TABLE EXTENDED

Measured results (Serverless SQL Warehouse, incremental merge model with auto_liquid_cluster: true):

Default incremental_apply_config_changes: false
Queries (model execution) 13 5
Model execution time 13.89s 6.55s
get_relation_config overhead 3.70s 0s
Speedup 2.12x
Test assets used for benchmarking

dbt_project.yml:

name: 'perf_test'
version: '1.0.0'
profile: 'perf_test'

model-paths: ["models"]
macro-paths: ["macros"]
test-paths: ["tests"]
seed-paths: ["seeds"]

target-path: "target"
clean-targets:
  - "target"
  - "dbt_packages"

flags:
  use_materialization_v2: false

models/incremental_merge_test.sql (default run):

{{
  config(
    materialized='incremental',
    incremental_strategy='merge',
    unique_key='id',
    auto_liquid_cluster=true
  )
}}

SELECT
  id, name, category, amount, updated_at
FROM (
  VALUES
    (1, 'Alice', 'A', 100.0, current_timestamp()),
    (2, 'Bob', 'B', 200.0, current_timestamp()),
    (3, 'Charlie', 'A', 150.0, current_timestamp()),
    (4, 'Diana', 'C', 300.0, current_timestamp()),
    (5, 'Eve', 'B', 250.0, current_timestamp())
) AS t(id, name, category, amount, updated_at)

models/incremental_merge_test.sql (skip run — only config diff):

{{
  config(
    materialized='incremental',
    incremental_strategy='merge',
    unique_key='id',
    auto_liquid_cluster=true,
    incremental_apply_config_changes=false
  )
}}

Steps: dbt run (initial table creation) → dbt run (incremental merge, default) → add incremental_apply_config_changes=falsedbt run (incremental merge, skip). Compare dbt.log from the last two runs.

Query-level breakdown (default run)
  1. 0.470s  CREATE TEMPORARY VIEW (temp relation)
  2. 0.290s  DESCRIBE TABLE EXTENDED (target)
  3. 0.180s  DESCRIBE TABLE EXTENDED (temp)
  4. 6.200s  MERGE INTO (model SQL)
  5. 0.360s  fetch_tags ← get_relation_config
  6. 0.350s  fetch_column_tags ← get_relation_config
  7. 0.480s  fetch_non_null_constraints ← get_relation_config
  8. 0.790s  fetch_primary_key_constraints ← get_relation_config
  9. 1.070s  fetch_foreign_key_constraints ← get_relation_config
 10. 0.320s  fetch_column_masks ← get_relation_config
 11. 0.330s  SHOW TBLPROPERTIES ← get_relation_config
 12. 0.350s  DESCRIBE TABLE EXTENDED ← get_relation_config
 13. 2.700s  OPTIMIZE
Query-level breakdown (skip run)
  1. 0.420s  CREATE TEMPORARY VIEW (temp relation)
  2. 0.260s  DESCRIBE TABLE EXTENDED (target)
  3. 0.160s  DESCRIBE TABLE EXTENDED (temp)
  4. 3.540s  MERGE INTO (model SQL)
  5. 2.170s  OPTIMIZE

Functional parity: apply_config_changeset (used by process_config_changes) handles all config types that the V1 inline code handled (tags, tblproperties, liquid_clustering, constraints) plus additional types (column_comments, column_tags, column_masks).

When incremental_apply_config_changes is true (default), behavior is unchanged — all 8 queries run and config changes are applied.

Checklist

  • I have run this code in development and it appears to resolve the stated issue
  • This PR includes tests, or tests are not required/relevant for this PR
  • I have updated the CHANGELOG.md and added information about my change to the "dbt-databricks next" section.

databricks#1402)

Replace inline config change detection/application in the V1 incremental
path with the existing `process_config_changes()` macro already used by V2.
This allows users to set `incremental_apply_config_changes: false` to skip
8 unnecessary information_schema queries per incremental model execution.

Co-authored-by: Isaac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

perf: V1 incremental path does not respect incremental_apply_config_changes flag

1 participant