Index.Rebuild() silently ignores DataCompression = None - the ALTER INDEX ... REBUILD is generated without DATA_COMPRESSION and the index stays compressed
Ninguém assumiu esta issue ainda.
Avaliação
- Dificuldade
- 4/5
- Tempo estimado
- 3-5 dias
- Facilidade para iniciantes
- 74/100
Direção de pesquisa
Comece em IndexBase.cs, em torno de Rebuild() e ScriptIndexRebuildOptions, e depois compare o caminho do índice inteiro com o caminho funcional de uma única partição. Leia em IndexScripter.cs e PhysicalPartitionCollectionBase.cs as partes relacionadas a ScriptCompression, GetCompressionCode e IsCompressionCodeRequired. Reproduza o exemplo do PowerShell no SQL Server; está concluído quando Rebuild() do índice inteiro emite DATA_COMPRESSION = NONE e remove a compactação.
Escrita pelo modelo de indexação a partir do texto da issue.
Descrição
Setting DataCompression = None on the physical partitions of a compressed index and calling Rebuild() does not decompress the index. The generated ALTER INDEX ... REBUILD statement contains no DATA_COMPRESSION clause at all, and SQL Server preserves the existing compression setting on a rebuild — so the call succeeds and silently does nothing. Setting any other compression type the same way works, and the single-partition overload Rebuild(partitionNumber) works for None too; only whole-index Rebuild() with None is affected.
Repro
# Index currently PAGE compressed
$index = $server.Databases["db"].Tables["t"].Indexes["ix"]
foreach ($p in $index.PhysicalPartitions) { $p.DataCompression = "None" }
$index.Rebuild()
# Generated: ALTER INDEX [ix] ON [dbo].[t] REBUILD PARTITION = ALL WITH (PAD_INDEX = OFF, ...)
# Expected: ... WITH (..., DATA_COMPRESSION = NONE)
# Result: no error, index still PAGE compressed
dbatools has worked around this for years in Set-DbaDbCompression by dropping to raw T-SQL for None only (Set-DbaDbCompression.ps1#L355-L373). The workaround comment links the original report on UserVoice (feedback.azure.com item 34080112), which is lost since that platform was retired — hence this re-file.
Mechanism
Rebuild() keeps optimizePartitionNumber = -1 and ends in scripter.GetRebuildScript(false, -1) (IndexBase.cs#L1093-L1102, #L1299-L1330).
In ScriptIndexRebuildOptions, the whole-index case (rebuildPartitionNumber == -1) reuses ScriptCompression — the same helper CREATE scripting uses (IndexScripter.cs#L1866-L1893). That helper calls GetCompressionCode(isOnAlter: false, isOnTable: false, sp) (IndexScripter.cs#L949-L965) — and GetCompressionCode only emits DATA_COMPRESSION = NONE when isOnAlter is true (PhysicalPartitionCollectionBase.cs#L560-L571):
if (isOnAlter && (noneCompressionCount > 0))
{
if (noneCompressionCount == this.Count)
{
return string.Format(SmoApplication.DefaultCulture, "DATA_COMPRESSION = NONE");
}
...
Omitting NONE is correct for CREATE (it is the default there), but on a REBUILD the omission means "keep what you have". The design already anticipates this distinction — IsCompressionCodeRequired(bool isOnAlter) returns isOnAlter when every partition is None, with the comment "If it's asked by alter method then have to generate in any case" (PhysicalPartitionCollectionBase.cs#L160-L181) — the rebuild path just never passes true.
The single-partition path is the proof by contrast: Rebuild(partitionNumber) uses the dirty-state check and the per-partition GetCompressionCode(partitionNumber), which returns DATA_COMPRESSION = NONE unconditionally (PhysicalPartitionCollectionBase.cs#L132-L146) — so rebuilding one partition to None works.
Table.Rebuild() shares this scripting helper, so the table-level equivalent is likely affected as well (not separately verified).
Suggested fix
In the rebuildPartitionNumber == -1 branch of ScriptIndexRebuildOptions, script compression with ALTER semantics instead of CREATE semantics — e.g. give ScriptCompression an isOnAlter parameter and pass true from the rebuild path (both for the IsCompressionCodeRequired gate and the GetCompressionCode call). That makes an all-None dirty collection emit DATA_COMPRESSION = NONE, matching what Rebuild(partitionNumber) already does.
Happy to submit a PR along those lines if that helps.
This was created by Claude and reviewed by Andreas Jordan.
- Linguagem predominante
- C#
- Estrelas
- 143
- Forks
- 29
- Métricas de merge de PRs
- Nenhum PR com merge em 30d
Preparar o ambiente
Este projeto não oferece contêiner de desenvolvimento, Dockerfile nem guia de contribuição, então a configuração fica por sua conta: comece pelo README e veja nosso guia da primeira contribuição para os passos gerais.
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de microsoft/sqlmanagementobjects
-
Path parsing functions are incorrect when running on LinuxTalvez já em andamento @shueybubbles assumiu há 3 dias. Aberta
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 70/100
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 62/100
-
Dificuldade 3/5 1-2 dias Facilidade para iniciantes 72/100
-
Dificuldade 3/5 1-2 dias Facilidade para iniciantes 78/100
-
SmoMetadataProvider throws bare NullReferenceException when the current database cannot be resolved (Azure/Fabric endpoint)Talvez já em andamento @jtorres assumiu há 58 dias. Aberta
Dificuldade 3/5 1-2 dias Facilidade para iniciantes 68/100
Todas as issues de microsoft/sqlmanagementobjects
Issues semelhantes
-
agentic-workflows untriaged
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 82/100
Mantenedores costumam responder em até 1 dia
-
VS Code
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 65/100
AlamoEngine-Tools/pg-starwarsgame-lsp#207 ·
Mantenedores costumam responder em até 1 dia
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 76/100
elsa-workflows/elsa-core#8593 ·
Mantenedores costumam responder em até 1 dia
-
GpioController.QueryComponentInformation() throws NotSupportedException with RaspberryPi3DriverAbertauntriaged
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 78/100
-
WebSocket upgrade check is case-sensitive for `Upgrade`Talvez já em andamento @S0CloseYetS0Far assumiu hoje. Abertabug good first issue severity:low
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 88/100