Eu gostaria de executar uma consulta que encontra números primos e gostaria de executá-la para sempre.
@Solomon Rutzky nesta página Números primos em um determinado intervalo , nos dão um bom exemplo da peneira de Eratóstenes .
DECLARE @RangeStart INT = 1,
@RangeEnd INT = 100000;
DECLARE @HowMany INT = CEILING((@RangeEnd - @RangeStart + 1) / 2.0);
;WITH frst AS
(
SELECT tmp.thing1
FROM (VALUES (0), (0), (0), (0), (0), (0), (0), (0), (0), (0)) tmp(thing1)
), scnd AS
(
SELECT 0 AS [thing2]
FROM frst t1
CROSS JOIN frst t2
CROSS JOIN frst t3
), base AS
(
SELECT TOP( CONVERT( INT, CEILING(SQRT(@RangeEnd)) ) )
ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS [num]
FROM scnd s1
CROSS JOIN scnd s2
), nums AS
(
SELECT TOP (@HowMany)
(ROW_NUMBER() OVER (ORDER BY (SELECT 1)) * 2) +
(@RangeStart - 1 - (@RangeStart%2)) AS [num]
FROM base b1
CROSS JOIN base b2
), divs AS
(
SELECT [num]
FROM base b3
WHERE b3.[num] > 4
AND b3.[num] % 2 <> 0
AND b3.[num] % 3 <> 0
)
SELECT given.[num] AS [Prime]
FROM (VALUES (2), (3)) given(num)
WHERE given.[num] >= @RangeStart
UNION ALL
SELECT n.[num] AS [Prime]
FROM nums n
WHERE n.[num] BETWEEN 5 AND @RangeEnd
AND n.[num] % 3 <> 0
AND NOT EXISTS (SELECT *
FROM divs d
WHERE d.[num] <> n.[num]
AND n.[num] % d.[num] = 0
);
Assim, podemos facilmente gerar uma lista de todos os números primos de 0 a 100.
Mas digamos que eu queira que a consulta seja executada pelos próximos 20 anos, então defino como limite um número muito grande:
DECLARE @RangeStart INT = 1,
@RangeEnd INT = 100000000000000000000000000000000000000000000000000;
E é aí que vem o problema: como manter essa consulta pelos próximos 20 anos?
Porque a Peneira de Eratóstenes tem uma peculiaridade:
Se for interrompido, você deve reiniciar desde o início.
Então minhas dúvidas começam aqui:
- Como posso mudar a CPU, atualizar a RAM, mudar o disco rígido, etc...
- Como posso gerenciar um cenário de desastre de failover para evitar que esse script pare?
- O failover garantirá que a consulta não será interrompida?
- Redundância de nuvem e failover para diferentes provedores (Azure / AWS / GCE) isso garantirá que o script não pare?
- E se o failover for do Azure para AWS em 2 partes diferentes do globo? Esse failover manterá o procedimento armazenado em execução?
E agora a parte de recuperação de desastres:
- Posso fazer um backup, digamos, todo mês, do status desse procedimento armazenado e, eventualmente, retomar a partir dessa imagem?
- Se eu executar o procedimento armazenado em uma máquina virtual e tirar instantâneos, posso retomar o procedimento armazenado?
Sei com certeza que alguém está fazendo isso: este banco de dados online de números primos fatorados http://factordb.com/status.php conseguiu aumentar de 200 MB (em 2014) para quase 800 MB hoje (2019).
Seria mais fácil modificar o script para que ele escrevesse o último valor ou um valor a cada n vezes para que você pudesse reiniciar o script com o último valor conhecido em caso de falha. O hardware Linux é bastante confiável, tive servidores que tiveram mais de 4 anos de atividade, mas é claro que nada é garantido.
1º pensamento
Você tem um problema XY. Você precisa usar um algoritmo que permite reiniciar a partir de um ponto específico.
Revisão de código
Dividend.num <=@endnum
existe em dois lugares.Divisor.num between 2 and sqrt(dividend.num) is more restrictive than
Divisor.num <= @endnum`.NOT EXISTS
usa o intervalo apropriado de linhas para todas asDividend
linhas...Dividend.num <= @endnum
paraDividend.num between @startnum and @endnum
Notas do algoritmo
Agora que a instrução SQL define um RANGE... você pode executar por 20 anos
Para todos os números entre A e B:
Ao contrário do método Segmented Sieve, você está usando todos os valores para cada pedaço, não apenas Primes conhecidos.
Peneira Segmentada
Mudanças necessárias para implementar a peneira segmentada
DELETE FROM T16M WHERE num in ( .... )
)Notas
A vida útil do universo (e a quantidade necessária de espaço em disco) provavelmente o limitará ao tamanho do número que você pode encontrar.
Perguntas Originais Preocupações
Aos 40 anos e ainda em andamento, um dos programas de computador mais antigos é o Voyager 1/Voyager 2.
https://www.space.com/26041-nasa-voyager-probes-solar-system-legacy.html
A adição/substituição de discos pode ser feita via sistema SAN.
A adição de CPU/RAM física a quente pode exigir equipamento não Intel.
Chunking
Os usuários do Oracle podem usar
DMBS_PARALLEL_EXECUTE
para criar Chunks e executá-los. Outros RDBMS precisarão implementar sua própria API que faça isso.Observação preliminar: Houve alguns comentários (agora excluídos) sobre a viabilidade de mudar para uma abordagem, que permite reiniciar a busca de primos baseada na peneira de Eratóstenes…
Algo ao longo do seguinte deve funcionar:
Configurando o Estágio/Semente:
Esteja pronto para fazer o trabalho sempre que possível:
Veja em ação: db<>fiddle .
NB : Apenas a ideia - T-SQL não é realmente minha xícara de chá…
Por favor, comente, se e como isso requer ajuste / mais detalhes.