Skip to content

Commit c5203ab

Browse files
Get-DbaDbTable: Fix performance regression with URN filter and config option (#10140)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 8ec985f commit c5203ab

3 files changed

Lines changed: 78 additions & 1 deletion

File tree

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,7 @@ allcommands.ps1
6060
/.shadowgit.git
6161
/.claude
6262
publish.ps1
63+
64+
PR_BODY.md
65+
66+
PR_DESCRIPTION.md

private/configurations/settings/commands.ps1

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,6 @@ Set-DbatoolsConfig -FullName 'commands.initialize-credssp.bypass' -Value $false
1616

1717
# Test-ElevationRequirement
1818
Set-DbatoolsConfig -FullName 'commands.test-elevationrequirement.disable' -Value $false -Initialize -Validation bool -Description "Disable elevation (run as admin) requirement"
19+
20+
# Get-DbaDbTable
21+
Set-DbatoolsConfig -FullName 'commands.get-dbadbtable.clearandinitialize' -Value $false -Initialize -Validation bool -Description "Controls whether Get-DbaDbTable uses ClearAndInitialize to load all table properties in one optimized query. Set to true to enable the optimization, which loads all properties in a single query but clears already loaded SMO properties. Keep at false when reusing SMO objects across multiple calls (e.g. in Copy-DbaDbTableData)."

public/Get-DbaDbTable.ps1

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,77 @@ function Get-DbaDbTable {
209209
$null = $properties.Add('IsEdge')
210210
}
211211

212-
$db.Tables.ClearAndInitialize('', [string[]]$properties)
212+
# Build URN filter for server-side filtering when -Table or -Schema is specified
213+
# This avoids loading ALL tables when only specific ones are requested
214+
$urnFilter = ''
215+
if ($fqTns -or $Schema) {
216+
$filterConditions = [System.Collections.ArrayList]@()
217+
218+
# Add schema filter conditions from -Schema parameter
219+
if ($Schema) {
220+
$schemaConditions = [System.Collections.ArrayList]@()
221+
foreach ($s in $Schema) {
222+
$null = $schemaConditions.Add("@Schema='$s'")
223+
}
224+
if ($schemaConditions.Count -eq 1) {
225+
$null = $filterConditions.Add($schemaConditions[0])
226+
} elseif ($schemaConditions.Count -gt 1) {
227+
$null = $filterConditions.Add("($($schemaConditions -join ' or '))")
228+
}
229+
}
230+
231+
# Add table name filter conditions from -Table parameter
232+
if ($fqTns) {
233+
$tableConditions = [System.Collections.ArrayList]@()
234+
foreach ($fqTn in $fqTns) {
235+
# Skip if database is specified and doesn't match current database
236+
if ($fqTn.Database -and $fqTn.Database -ne $db.Name) {
237+
continue
238+
}
239+
240+
# Only add the table name filter, schema is handled above via -Schema parameter
241+
# or from the parsed table name if -Schema was not specified
242+
$tableParts = [System.Collections.ArrayList]@()
243+
244+
# Add schema from table name only if -Schema parameter was not specified
245+
if ($fqTn.Schema -and -not $Schema) {
246+
$null = $tableParts.Add("@Schema='$($fqTn.Schema)'")
247+
}
248+
249+
if ($fqTn.Table) {
250+
$null = $tableParts.Add("@Name='$($fqTn.Table)'")
251+
}
252+
253+
if ($tableParts.Count -gt 0) {
254+
if ($tableParts.Count -eq 1) {
255+
$null = $tableConditions.Add($tableParts[0])
256+
} else {
257+
$null = $tableConditions.Add("($($tableParts -join ' and '))")
258+
}
259+
}
260+
}
261+
262+
if ($tableConditions.Count -gt 0) {
263+
if ($tableConditions.Count -eq 1) {
264+
$null = $filterConditions.Add($tableConditions[0])
265+
} else {
266+
$null = $filterConditions.Add("($($tableConditions -join ' or '))")
267+
}
268+
}
269+
}
270+
271+
if ($filterConditions.Count -gt 0) {
272+
# ClearAndInitialize expects XPath-style filter WITH outer brackets
273+
# e.g., "[@Schema='dispo' and @Name='t_auftraege']"
274+
# See: https://learn.microsoft.com/en-us/dotnet/api/microsoft.sqlserver.management.smo.smocollectionbase.clearandinitialize
275+
$urnFilter = "[$($filterConditions -join ' and ')]"
276+
Write-Message -Level Verbose -Message "Using URN filter: $urnFilter"
277+
}
278+
}
279+
280+
if (Get-DbatoolsConfigValue -FullName 'commands.get-dbadbtable.clearandinitialize') {
281+
$db.Tables.ClearAndInitialize($urnFilter, [string[]]$properties)
282+
}
213283

214284
if ($fqTns) {
215285
$tables = @()

0 commit comments

Comments
 (0)