Índice de Documents (relatórios de documentos)
Esta página explica o índice IX_Documents_SubscriptionId_CreationDateUtc, criado na atualização para a versão 3.0.0 (SIG-1919), e o que fazer se a criação automática falhar. Ele se aplica a todas as instâncias que atualizam de uma versão anterior à 3.0.0.
É fortemente recomendado fazer a atualização em um horário de pouco uso. Enquanto o índice não existe, a aplicação funciona normalmente. O custo é que os relatórios de documentos podem ficar lentos ou estourar o tempo limite em organizações com muitos documentos.
O que esse índice melhora
Os relatórios de documentos da organização, do usuário e da pasta carregam todos os documentos de um período, filtrando pela assinatura (SubscriptionId) e ordenando pela data de criação (CreationDateUtc). Sem um índice com essas duas colunas, o banco de dados precisa ordenar um volume grande de documentos antes de devolver as linhas, o que causava timeout na geração do relatório mensal de organizações grandes.
IX_Documents_SubscriptionId_CreationDateUtc
chaves: SubscriptionId (crescente), CreationDateUtc (crescente)
Se um relatório estourar o tempo limite, o log da aplicação registra um aviso sugerindo aumentar ReportDatabaseCommandTimeoutSeconds ou verificar se o índice existe.
Como o processo automático funciona
- Migração (
AddDocumentsReportIndex). Executada na primeira inicialização. Ela não cria o índice, para não bloquear a tabelaDocumentsdurante a atualização. - Enfileiramento na inicialização. O
DocumentsReportIndexBuilderStarterverifica se o índice existe. Se não existir (ou se não conseguir verificar), enfileira no Hangfire oCreateDocumentsReportIndexJob(fila Low, até 3 tentativas, sem execução concorrente). Isso se repete a cada inicialização enquanto o índice não existir. - Job
CreateDocumentsReportIndexJob. Se o índice já existe, não faz nada. Caso contrário, identifica a edição do SQL Server e cria o índice comSORT_IN_TEMPDB = ONe timeout deDocumentsReportIndexCommandTimeoutSeconds(padrão7200):- ONLINE (não bloqueia a tabela) no Azure SQL Database, SQL Managed Instance e SQL Server Enterprise ou Developer.
- OFFLINE nas demais edições, o que bloqueia a tabela
Documentsaté terminar. O job registra um aviso no log. - Se a criação ONLINE falhar por um erro que não seja timeout, o job tenta criar OFFLINE. Se a criação ONLINE estourar o timeout, ela não é repetida OFFLINE, para não bloquear a tabela por ainda mais tempo.
Como acompanhar
- No painel do Hangfire (
/hangfire), acompanhe oCreateDocumentsReportIndexJob. - Nos logs da aplicação, procure por
Creating IX_Documents_SubscriptionId_CreationDateUtc,created successfullyouFailed to create. - No banco de dados:
SELECT name, is_disabled FROM sys.indexes
WHERE name = 'IX_Documents_SubscriptionId_CreationDateUtc' AND object_id = OBJECT_ID('Documents');
O que fazer se o processo automático falhar
O job falhou se ele esgotou as 3 tentativas no Hangfire, ou se os logs mostram timeout ou deadlock (erro SQL 1205) e a consulta acima não retorna o índice.
1. Aumentar o timeout e reiniciar
Aumente DocumentsReportIndexCommandTimeoutSeconds (veja Configurações General) e reinicie a aplicação. O job é enfileirado novamente na inicialização.
2. Criar o índice manualmente
Se ainda estourar o tempo limite, crie o índice no banco de dados. Faça isso em uma janela de baixo tráfego e em uma única sessão: duas criações ONLINE simultâneas na mesma tabela entram em deadlock na troca final de locks, e o IF NOT EXISTS não protege contra execução concorrente. Em edições sem suporte a ONLINE (SQL Server Standard e Express), use ONLINE = OFF, que bloqueia a tabela durante a criação.
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = 'IX_Documents_SubscriptionId_CreationDateUtc' AND object_id = OBJECT_ID('Documents'))
CREATE INDEX [IX_Documents_SubscriptionId_CreationDateUtc] ON [Documents] ([SubscriptionId] ASC, [CreationDateUtc] ASC)
WITH (ONLINE = ON, SORT_IN_TEMPDB = ON);
Cuidados:
- Deadlock. O build ONLINE disputa locks com as escritas da aplicação e pode causar deadlock (erro 1205); a vítima pode ser uma transação da aplicação em vez do build. Depois da criação, verifique nos logs da aplicação se houve erros 1205 no período.
- Azure SQL Database. A criação de índice é sempre registrada integralmente no log de transações, então o tempo depende do limite de log do nível de serviço. Níveis baixos sofrem throttle (espera
LOG_RATE_GOVERNOR; a esperaCXCONSUMERé benigna). Se puder, escale o nível de serviço antes de iniciar o build, pois trocar o nível no meio derruba a criação em andamento. - Criação retomável (opcional). No SQL Server 2019 ou superior e no Azure SQL, adicione
RESUMABLE = ONaoWITHpara que uma interrupção não descarte o progresso (consultesys.index_resumable_operationse useALTER INDEX ... RESUMEouABORT).RESUMABLE = ONnão pode ser combinado comSORT_IN_TEMPDB = ON; remova essa opção.
3. Confirmar
Execute a consulta da seção Como acompanhar: o índice deve estar presente e is_disabled = 0. Com o índice criado, o job termina sem refazer a criação na próxima inicialização.