Pular para o conteúdo principal

Í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.

observação

É 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​

  1. Migração (AddDocumentsReportIndex). Executada na primeira inicialização. Ela não cria o índice, para não bloquear a tabela Documents durante a atualização.
  2. Enfileiramento na inicialização. O DocumentsReportIndexBuilderStarter verifica se o índice existe. Se não existir (ou se não conseguir verificar), enfileira no Hangfire o CreateDocumentsReportIndexJob (fila Low, até 3 tentativas, sem execução concorrente). Isso se repete a cada inicialização enquanto o índice não existir.
  3. 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 com SORT_IN_TEMPDB = ON e timeout de DocumentsReportIndexCommandTimeoutSeconds (padrão 7200):
    • 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 Documents até 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 o CreateDocumentsReportIndexJob.
  • Nos logs da aplicação, procure por Creating IX_Documents_SubscriptionId_CreationDateUtc, created successfully ou Failed 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 espera CXCONSUMER é 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 = ON ao WITH para que uma interrupção não descarte o progresso (consulte sys.index_resumable_operations e use ALTER INDEX ... RESUME ou ABORT). RESUMABLE = ON não pode ser combinado com SORT_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.

Ver em Markdown