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 / 47279
Accepted
AK_
AK_
Asked: 2013-07-31 05:55:08 +0800 CST2013-07-31 05:55:08 +0800 CST 2013-07-31 05:55:08 +0800 CST

SQL Server Ajustando uma tabela para inserções massivas

  • 772

Estou tentando resolver um problema de desempenho e preciso de conselhos.

Eu tenho uma tabela, que cerca de duas vezes por dia tem um grande aumento de inserções chegando, e exatamente ao mesmo tempo todo mundo está tentando ler nela. Então eu tenho bloqueios e tudo se torna dolorosamente lento.

Meus requisitos de desempenho são os seguintes:

  1. muitos escritores, de diferentes fontes, e eu prefiro que cada escrita seja atômica.
  2. não me importo com a ordem das gravações, o número 7 pode vir antes do número 3.
  3. as gravações devem terminar o mais rápido possível, quero que os escritores esperem o mínimo de tempo possível.
  4. os dados nunca são atualizados , apenas inseridos.
  5. Eu tenho muitos muitos leitores.
  6. os leitores querem ver o instantâneo mais atualizado possível no momento da leitura.
  7. Posso viver com os leitores vendo dados atrasados ​​(10 a 20 segundos)
  8. Eu preciso ocasionalmente fazer consultas complexas e grandes sobre esses dados, então preciso de vários índices nele.

Como você abordaria isso e como implementaria isso com o SQL Server?


Estou pensando em dividir em 2 tabelas... uma para as inserções, e outra para leitura, e um trabalhador movimentando os dados.

as consultas grandes rodarão somente na segunda, os leitores que precisam de dados atualizados, podem rodar na segunda, e completam o que precisam da primeira.

sql-server sql-server-2008
  • 2 2 respostas
  • 2035 Views

2 respostas

  • Voted
  1. Best Answer
    Aaron Bertrand
    2013-07-31T07:17:30+08:002013-07-31T07:17:30+08:00

    Uma solução que usei foi encadear gravações em várias tabelas de preparação e, em seguida, coletar os dados em lotes. Colocamos as tabelas de preparação em seus próprios grupos de arquivos para tentar segregar a E/S o máximo possível, embora tenhamos acabado com duas tabelas em cada LUN disponível, em vez de cada tabela obter sua própria E/S dedicada.

    Como você disse que a ordem das gravações não importa, isso pode ser viável, mas não sei se 20 segundos serão suficientes para fazer isso funcionar e ainda não encontrar muitos bloqueios.

    Então, digamos que temos uma tabela base como esta, que é de onde todos leem (e atualmente escrevem):

    CREATE TABLE dbo.StockData
    (
      StockID INT,
      ...other info...
    );
    

    Então temos tabelas de preparação como esta, onde vamos escrever:

    CREATE TABLE staging.StockData0
    (
      StockID INT,
      ...other info...
    );
    
    CREATE TABLE staging.StockData1
    (
      StockID INT,
      ...other info...
    );
    
    ... up to StockData9
    

    *Não se preocupe em imitar todos os índices não agrupados, restrições etc. nessas tabelas de preparação,

    Em seguida, supondo que você tenha inserções singleton por meio de um procedimento armazenado, altere o procedimento armazenado para usar SQL dinâmico e insira em uma das 10 tabelas com base no StockIDvalor:

    DECLARE @sql NVARCHAR(MAX) = N'INSERT staging.StockData'
      + CONVERT(CHAR(1), @StockID % 10 + '(StockID, cols...)
        SELECT @StockID, @params...;';
    
    EXEC sp_executesql @sql, N'@StockID INT, @params...', @StockID, @params...;
    

    Em seguida, tenha um trabalho em segundo plano que execute uma operação de metadados muito rápida, movendo essas tabelas para um esquema fictício - isso minimiza a quantidade de tempo gasto bloqueando a capacidade dos usuários de escrever enquanto você move esses dados para a tabela real (que agora você pode controle muito melhor do que gravações esporádicas de todo o lugar). Portanto, primeiro crie uma segunda cópia das tabelas em um esquema diferente:

    CREATE SCHEMA shadow  AUTHORIZATION dbo;
    CREATE SCHEMA holding AUTHORIZATION dbo;
    GO
    
    CREATE TABLE shadow.StockData0
    (
      StockID INT,
      ...other info...
    );
    
    -- repeat for 1-9
    

    Agora o trabalho faria isso:

    TRUNCATE TABLE shadow.StockData0;
    
    BEGIN TRANSACTION;
    
      ALTER SCHEMA holding TRANSFER staging.StockData0;
      ALTER SCHEMA staging TRANSFER shadow.StockData0;
    
    COMMIT TRANSACTION;
    
    ALTER SCHEMA shadow TRANSFER holding.StockData0;
    
    -- repeat for 1-9 (I actually used dynamic SQL in a loop
    -- so I wouldn't have to repeat myself ten times...
    

    Eu escrevi sobre esta parte aqui e aqui .

    O trabalho continuaria inserindo lotes na tabela principal, com um atraso entre eles, para permitir que algumas leituras acontecessem.

    BEGIN TRANSACTION;
    
      INSERT dbo.StockData(StockID, ...cols...)
        SELECT StockID, ...cols...
        FROM holding.StockData0;
    
    COMMIT TRANSACTION;
    
    WAITFOR DELAY '00:00:01';
    
    -- repeat for 1-9
    

    Isso foi há vários anos, e algo que não me ocorreu na época (o que me lembro agora também, depois de ver o outro link postado por wBob) é que usar TABLOCKdentro dessas transações pode ajudar a acelerar as inserções (embora você vai querer testar com base no volume, nível de isolamento, etc).

    Também pode ser útil (mesmo com todo esse trabalho) habilitar o isolamento de instantâneo confirmado de leitura e/ou se você estiver no Enterprise Edition considerando o particionamento (e alinhar as tabelas de preparação a essas partições).

    • 5
  2. wBob
    2013-07-31T08:28:55+08:002013-07-31T08:28:55+08:00

    A equipe do SQL CAT postou um artigo sobre um tópico semelhante:

    Carregando dados em massa em uma tabela com consultas simultâneas

    • 2

relate perguntas

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Quanto "Padding" coloco em meus índices?

  • Existe um processo do tipo "práticas recomendadas" para os desenvolvedores seguirem para alterações no banco de dados?

  • Como determinar se um Índice é necessário ou necessário

  • Downgrade do SQL Server 2008 para 2005

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • 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

    Conceder acesso a todas as tabelas para um usuário

    • 5 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
    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
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +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