AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 254446
Accepted
Francesco Mantovani
Francesco Mantovani
Asked: 2019-11-30 05:39:05 +0800 CST2019-11-30 05:39:05 +0800 CST 2019-11-30 05:39:05 +0800 CST

Como manter uma consulta que é executada para sempre?

  • 772

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

insira a descrição da imagem aqui

t-sql failover
  • 3 3 respostas
  • 237 Views

3 respostas

  • Voted
  1. pixiemops
    2019-11-30T05:49:42+08:002019-11-30T05:49:42+08:00

    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.

    • 4
  2. Best Answer
    Michael Kutz
    2019-12-04T14:34:27+08:002019-12-04T14:34:27+08:00

    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 <=@endnumexiste em dois lugares.
      • Livre-se do 2º
    • Divisor.num between 2 and sqrt(dividend.num) is more restrictive than Divisor.num <= @endnum`.
      • livrar-se do menos restritivo.
    • Como o NOT EXISTSusa o intervalo apropriado de linhas para todas as Dividendlinhas...
      • Você pode mudar com segurança Dividend.num <= @endnumparaDividend.num between @startnum and @endnum
    • Gerar T16M uma vez permitirá que você reutilize os resultados
      • Ou seja: make é uma tabela regular

    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:

    1. Divida-os em intervalos menores e gerenciáveis.
    2. Executar n pedaços em paralelo

    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

    • a chave é usar os valores da tabela T16M, não um CTE.
    • Modifique o código para EXCLUIR os números não primos em T16M. (por exemplo DELETE FROM T16M WHERE num in ( .... ))
    • Execute em série cada pedaço na ordem mais baixa para a mais alta.

    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

    1. Sistema de longa duração

    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 Voyager emprega três sistemas de computador redundantes duplos por espaçonave. https://history.nasa.gov/computers/Ch6-2.html

    1. adicionando CPU/RAM/discos

    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.

    Recursos de CPU e memória podem ser adicionados sem interrupções ao sistema.... https://en.wikipedia.org/wiki/IBM_Z

    Chunking

    Os usuários do Oracle podem usar DMBS_PARALLEL_EXECUTEpara criar Chunks e executá-los. Outros RDBMS precisarão implementar sua própria API que faça isso.

    • 4
  3. Abecee
    2019-12-04T12:38:30+08:002019-12-04T12:38:30+08:00

    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:

    CREATE TABLE Prime (
        id INT NOT NULL IDENTITY PRIMARY KEY,
        prime INT NOT NULL UNIQUE
    );
    CREATE TABLE LastOne (
        id INT NOT NULL PRIMARY KEY
    );
    BEGIN TRANSACTION;
      INSERT INTO Prime (prime) VALUES (2);
      INSERT INTO LastOne VALUES (2);
    COMMIT;
    

    Esteja pronto para fazer o trabalho sempre que possível:

    CREATE PROC dbo.SieveOfEratosthenes AS
    DECLARE
        @nextPrimeCandidate INT = NULL
    BEGIN
      SET @nextPrimeCandidate = (
        SELECT id + 1
        FROM LastOne AS Dividend
        WHERE
          (Dividend.id + 1) % 2 = 1
          AND
          NOT EXISTS (
            SELECT 1
            FROM Prime
            WHERE
              prime BETWEEN 2 AND SQRT(Dividend.id + 1)
              AND
              (Dividend.id + 1) % prime = 0
        )
      )
      ;
      BEGIN TRANSACTION
        IF (@nextPrimeCandidate IS NOT NULL)
        INSERT INTO Prime (prime) VALUES (@nextPrimeCandidate);
        UPDATE LastOne SET id = id + 1;
      COMMIT;
    END;
    

    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.

    • 0

relate perguntas

  • Como alterar as configurações do gerenciador de configuração do servidor SQL usando o TSQL?

  • Como posso obter uma lista de nomes e tipos de coluna de um conjunto de resultados?

  • MS SQL: Use o valor calculado para calcular outros valores

  • Como posso saber se um banco de dados SQL Server ainda está sendo usado?

  • Implementando uma consulta PIVOT

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve