9.4 KiB
Fila de associações — referências, memória e índices isolados
Seguimento: leituras concorrentes e confirmação individual, com quatro identidades sintéticas e preservação dos dados anteriores da base de provas. A evidência adicional não constitui validação da capacidade de implantação ou revisão visual.
02/11/2026. Continuação local da optimização da fila. Foram tratados dois pontos que permaneciam por avaliar: documentos com 100 linhas e a contribuição do índice de revisão sozinho versus o par experimental. A avaliação encontrou um custo de memória e originou uma melhoria adicional de código, sem alterar dados do destino.
Alteração funcional
A fila passa a seleccionar apenas ID/versão, nome da raiz e referências explícitas. Para rascunhos, o PostgreSQL extrai os IDs de serviços das linhas com WITH ORDINALITY, preservando a ordem; descrições, preços e restantes conteúdos documentais não são transferidos para a cache de descrição da página. Dependências de clientes/serviços seleccionam apenas ID/versão.
O percurso, a deduplicação, os grupos de até 500 IDs, os filtros, as permissões e a forma da resposta continuam iguais. Os IDs calculados são internos e não acrescentam um campo público à API. Nenhuma associação é inferida ou propagada.
A projecção só se aplica à listagem. Prévia e confirmação continuam a carregar e a resumir criptograficamente os registos completos, incluindo conteúdo não apresentado na fila. O código desde preview() até confirm() continua igual ao de 340f3bb, após normalizar fins de linha. Alterar conteúdo de uma dependência, mantendo as mesmas referências, continua a invalidar uma conferência anterior.
Ensaio novo, sem repetir a comparação anterior
Base sgf_tempo_test, role sgf_test_runner, cluster sgf_modular_regression_2576427d1939, porta 55439, PHP 8.4.27. Foram reutilizados os resultados válidos anteriores; não se repetiu a matriz de 1 000/5 000/10 000 da primeira optimização, a regressão geral ou o build React.
A nova fixture contém 10 000 registos em cada uma das quatro áreas. As primeiras 100 prestações e os seus 100 rascunhos de facturação têm 100 linhas, com blocos distintos de serviços: uma página de 100 referencia 10 000 serviços. Uma prestação apresenta 101 dependências; um rascunho de facturação, 102. Foram ensaiadas páginas de 25/100 e descrições sintéticas de 128 e 1 000 bytes por linha.
As quatro variantes usam a mesma fixture por perfil: código anterior à projecção sem índices; projecção sem índices; projecção com índice de revisão; projecção com o par. A fonte anterior foi preservada antes da alteração, fora da raiz web, alterando apenas o nome da classe para a prova. O launcher verifica a integridade da cópia; os hashes original/final constam do resumo. Não se trata de um segundo percurso de produção.
São três amostras quentes e sequenciais por cenário, com recolha de ciclos PHP antes da medição e os mesmos limites diagnósticos: 3 s por SQL, 15 s observados entre consultas, 250 consultas e 192 MiB de memória PHP usada observada entre consultas. A configuração PHP existente é 512M e não foi alterada. Estes limites não são SLA ou quotas de produção.
Memória incremental por pedido
Máximo observado nas três amostras, em MiB, excluindo a memória já usada pelo kernel e pela fixture. A comparação abaixo é sem índices, na mesma fixture antes/depois da projecção.
| Descrição por linha | Área | Página | Antes | Depois |
|---|---|---|---|---|
| 128 bytes | Prestações | 25 | 6,13 | 4,21 |
| 128 bytes | Prestações | 100 | 24,11 | 16,65 |
| 128 bytes | Facturação | 25 | 7,34 | 4,85 |
| 128 bytes | Facturação | 100 | 28,98 | 19,23 |
| 1 000 bytes | Prestações | 25 | 8,28 | 4,21 |
| 1 000 bytes | Prestações | 100 | 32,42 | 16,65 |
| 1 000 bytes | Facturação | 25 | 11,55 | 4,85 |
| 1 000 bytes | Facturação | 100 | 45,49 | 19,23 |
No caso mais pesado, a redução foi de aproximadamente 58%. A memória após a projecção deixou de crescer com as descrições destes perfis, mas continua a crescer com o número de dependências que a página tem de apresentar. Não se deve aplicar a estimativa anterior de cerca de 1 MiB, obtida com uma linha por rascunho, ao cenário de 100 linhas.
As consultas PDO mantiveram-se iguais antes/depois da projecção: prestações 27/57 e facturação 31/61, para páginas de 25/100. O crescimento em relação à prova de uma linha deve-se aos grupos necessários para 2 500/10 000 serviços distintos, não a uma consulta por linha. As respostas de 100 registos ficaram perto de 0,79–0,80 MB, sem descrições documentais e sem diferenças de bytes entre as variantes de cada perfil.
Tempos e contribuição dos índices
Medianas em ms, descrições de 1 000 bytes por linha:
| Área / página | Antes, sem índices | Projecção, sem índices | Só revisão | Par experimental |
|---|---|---|---|---|
| Prestações / 25 | 668 | 729 | 97 | 226 |
| Prestações / 100 | 2 151 | 2 862 | 341 | 408 |
| Facturação / 25 | 815 | 905 | 112 | 127 |
| Facturação / 100 | 2 721 | 2 481 | 374 | 368 |
O benefício demonstrado da projecção é a memória e o menor conteúdo transportado para o PHP. Não acelerou todos os casos sem índices; houve também aumentos de latência, por exemplo nas prestações de 100. As fases têm ordem fixa e o cluster é partilhado com outra base sintética, pelo que três amostras não permitem atribuir toda a variação à alteração de código.
Na condição de 128 bytes, os filtros de clientes sem eventos/associados/retirados ficaram em 109/219/262 ms com o índice de revisão e 117/235/278 ms com o par. O segundo índice apareceu nos planos de associados/retirados, mas não mostrou ganho consistente que justifique recomendá-lo por estes dados. Isso não demonstra que seja inútil em todas as distribuições de histórico.
O índice de revisão ocupou 14 401 536 bytes (13,73 MiB); o segundo acrescentou 17 580 032 bytes (16,77 MiB). O par totalizou cerca de 30,50 MiB. Na primeira condição, criação + ANALYZE demoraram cerca de 1,02 s para revisão e 1,84 s para o par. Não são tempos de implantação real nem incluem criação concorrente, carga de escrita ou recuperação.
Para um futuro plano de implantação, o índice de revisão sozinho é o candidato mais parcimonioso a aprofundar. Não foi aplicado no destino. Todos os índices desta prova foram criados em savepoints na base sintética e desfeitos por rollback.
Testes e preservação
- 21 testes / 322 asserções afectados, aprovados. O novo caso verifica a ordem das referências, deduplicação, ausência do corpo/alias interno na resposta e recusa de confirmação após alteração apenas do conteúdo de uma dependência. Os casos anteriores continuam a verificar permissões, isolamento, versões, concorrência e recuperação.
- 1 ensaio / 25 499 asserções: 44 cenários, 132 pedidos medidos completos, sem limites atingidos; respostas completas idênticas entre as quatro variantes em cada perfil. As descrições marcadas da fixture não aparecem na resposta administrativa.
- Impressões digitais das oito tabelas antecedentes e catálogo de índices iguais antes das fixtures/depois do rollback. As sequências não foram repostas. As fixtures do ensaio de 132 pedidos foram desfeitas por rollback, preservando o estado que já existia na base de provas.
Medições finais · resumo, hashes e testes · diagnóstico inicial que revelou o custo de memória.
O código, os testes afectados e o novo ensaio são locais. Os seis registos protegidos, a cache bloqueada, as alterações alheias e as demonstrações permanecem intactos. Não houve ligação à instalação local/8039, decisão real, concessão pública, publicação, activação de Compras ou novo checkpoint.
Limitações e repetição
Não se declara validada a capacidade de implantação: não foram medidos utilizadores simultâneos, percentis de cauda, saturação, custo de escrita, implantação/recuperação de índices ou todas as distribuições multi-módulo. Os textos são repetitivos e sintéticos, abaixo do limite de 2 000 caracteres por descrição; não representam todos os payloads. A memória reportada não é a memória PostgreSQL nem uma estimativa por utilizador concorrente.
A resposta e o número de dependências cresceram: 100 rascunhos podem apresentar mais de 10 000 nós. Não se mediu o custo de renderização desse volume no navegador. Revisão visual permanece separada, sem tentativa pela via bloqueada.
O launcher fixado aceita scripts/module-association-compare.mjs fanout, depois do sync da cópia de regressão existente. Requer a fonte anterior e o respectivo hash preservados no directório privado da execução, cuja integridade verifica; não substitui automaticamente essa referência. Não executar prepare, reset ou testes na demonstração persistente. Não existe instrução de aplicar índices ao destino. A aceitação deste incremento e um checkpoint continuam a depender de decisão expressa.