Skip to content

Commit ba27fef

Browse files
committed
perf: make hot-path adapter catalog queries sargable
Optimizes the four highest-frequency catalog queries in the SQL Server adapter so they seek instead of scan: - list_relations_without_caching: filter by schema_id = SCHEMA_ID(@Schema) before computing names, instead of scanning every table+view in the database and post-filtering with LIKE on SCHEMA_NAME(...). - get_relation_without_caching: same predicate-pushdown; also switch identifier match from LIKE (no wildcards) to equality. - get_columns_in_relation: drop the wrapping CTE and the no-op ROW_NUMBER() OVER (PARTITION BY object_name(c.object_id) ...); the WHERE already pins one object_id. Order directly by c.column_id. - get_view_definition_sql: replace UPPER()-on-both-sides join across sys.views + sys.schemas with a single OBJECT_DEFINITION(OBJECT_ID( '[schema].[name]', 'V')) lookup. Preserves zero-row behavior when the view doesn't exist so the view materialization's diff-skip logic is unchanged.
1 parent 20e5905 commit ba27fef

2 files changed

Lines changed: 47 additions & 65 deletions

File tree

dbt/include/sqlserver/macros/adapters/columns.sql

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -69,31 +69,20 @@
6969
{% set query_label = apply_label() %}
7070
{% call statement('get_columns_in_relation', fetch_result=True) %}
7171
{{ get_use_database_sql(relation.database) }}
72-
with mapping as (
73-
select
74-
row_number() over (partition by object_name(c.object_id) order by c.column_id) as ordinal_position,
75-
c.name collate database_default as column_name,
76-
t.name as data_type,
77-
case
78-
when (t.name in ('nchar', 'nvarchar', 'sysname') and c.max_length <> -1) then c.max_length / 2
79-
else c.max_length
80-
end as character_maximum_length,
81-
c.precision as numeric_precision,
82-
c.scale as numeric_scale
83-
from sys.columns c {{ information_schema_hints() }}
84-
inner join sys.types t {{ information_schema_hints() }}
85-
on c.user_type_id = t.user_type_id
86-
where c.object_id = object_id('{{ 'tempdb..' ~ relation.include(database=false, schema=false) if '#' in relation.identifier else relation }}')
87-
)
88-
8972
select
90-
column_name,
91-
data_type,
92-
character_maximum_length,
93-
numeric_precision,
94-
numeric_scale
95-
from mapping
96-
order by ordinal_position
73+
c.name collate database_default as column_name,
74+
t.name as data_type,
75+
case
76+
when (t.name in ('nchar', 'nvarchar', 'sysname') and c.max_length <> -1) then c.max_length / 2
77+
else c.max_length
78+
end as character_maximum_length,
79+
c.precision as numeric_precision,
80+
c.scale as numeric_scale
81+
from sys.columns c {{ information_schema_hints() }}
82+
inner join sys.types t {{ information_schema_hints() }}
83+
on c.user_type_id = t.user_type_id
84+
where c.object_id = object_id('{{ 'tempdb..' ~ relation.include(database=false, schema=false) if '#' in relation.identifier else relation }}')
85+
order by c.column_id
9786
{{ query_label }}
9887
9988
{% endcall %}

dbt/include/sqlserver/macros/adapters/metadata.sql

Lines changed: 34 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -42,23 +42,22 @@
4242
{% macro sqlserver__list_relations_without_caching(schema_relation) -%}
4343
{% call statement('list_relations_without_caching', fetch_result=True) -%}
4444
{{ get_use_database_sql(schema_relation.database) }}
45-
with base as (
46-
select
47-
DB_NAME() as [database],
48-
t.name as [name],
49-
SCHEMA_NAME(t.schema_id) as [schema],
50-
'table' as table_type
51-
from sys.tables as t {{ information_schema_hints() }}
52-
union all
53-
select
54-
DB_NAME() as [database],
55-
v.name as [name],
56-
SCHEMA_NAME(v.schema_id) as [schema],
57-
'view' as table_type
58-
from sys.views as v {{ information_schema_hints() }}
59-
)
60-
select * from base
61-
where [schema] like '{{ schema_relation.schema }}'
45+
declare @schema_id int = schema_id('{{ schema_relation.schema }}');
46+
select
47+
DB_NAME() as [database],
48+
t.name as [name],
49+
'{{ schema_relation.schema }}' as [schema],
50+
'table' as table_type
51+
from sys.tables as t {{ information_schema_hints() }}
52+
where t.schema_id = @schema_id
53+
union all
54+
select
55+
DB_NAME() as [database],
56+
v.name as [name],
57+
'{{ schema_relation.schema }}' as [schema],
58+
'view' as table_type
59+
from sys.views as v {{ information_schema_hints() }}
60+
where v.schema_id = @schema_id
6261
{{ apply_label() }}
6362
{% endcall %}
6463
{{ return(load_result('list_relations_without_caching').table) }}
@@ -67,24 +66,22 @@
6766
{% macro sqlserver__get_relation_without_caching(schema_relation) -%}
6867
{% call statement('get_relation_without_caching', fetch_result=True) -%}
6968
{{ get_use_database_sql(schema_relation.database) }}
70-
with base as (
71-
select
72-
DB_NAME() as [database],
73-
t.name as [name],
74-
SCHEMA_NAME(t.schema_id) as [schema],
75-
'table' as table_type
76-
from sys.tables as t {{ information_schema_hints() }}
77-
union all
78-
select
79-
DB_NAME() as [database],
80-
v.name as [name],
81-
SCHEMA_NAME(v.schema_id) as [schema],
82-
'view' as table_type
83-
from sys.views as v {{ information_schema_hints() }}
84-
)
85-
select * from base
86-
where [schema] like '{{ schema_relation.schema }}'
87-
and [name] like '{{ schema_relation.identifier }}'
69+
declare @schema_id int = schema_id('{{ schema_relation.schema }}');
70+
select
71+
DB_NAME() as [database],
72+
t.name as [name],
73+
'{{ schema_relation.schema }}' as [schema],
74+
'table' as table_type
75+
from sys.tables as t {{ information_schema_hints() }}
76+
where t.schema_id = @schema_id and t.name = '{{ schema_relation.identifier }}'
77+
union all
78+
select
79+
DB_NAME() as [database],
80+
v.name as [name],
81+
'{{ schema_relation.schema }}' as [schema],
82+
'view' as table_type
83+
from sys.views as v {{ information_schema_hints() }}
84+
where v.schema_id = @schema_id and v.name = '{{ schema_relation.identifier }}'
8885
{{ apply_label() }}
8986
{% endcall %}
9087
{{ return(load_result('get_relation_without_caching').table) }}
@@ -96,12 +93,8 @@
9693

9794
{% macro sqlserver__get_view_definition_sql(relation) -%}
9895
{{ get_use_database_sql(relation.database) }}
99-
select object_definition(v.object_id) as definition
100-
from sys.views as v {{ information_schema_hints() }}
101-
inner join sys.schemas as s {{ information_schema_hints() }}
102-
on v.schema_id = s.schema_id
103-
where upper(s.name) = upper('{{ relation.schema }}')
104-
and upper(v.name) = upper('{{ relation.identifier }}')
96+
select object_definition(object_id('[{{ relation.schema }}].[{{ relation.identifier }}]', 'V')) as definition
97+
where object_id('[{{ relation.schema }}].[{{ relation.identifier }}]', 'V') is not null
10598
{% endmacro %}
10699

107100
{% macro sqlserver__get_relation_last_modified(information_schema, relations) -%}

0 commit comments

Comments
 (0)