Come si investiga l'esecuzione di un'istruzione BULK INSERT?


12

Sono principalmente uno sviluppatore .NET che utilizza Entity Framework ORM. Tuttavia, poiché non voglio fallire nell'uso dell'ORM , sto cercando di capire cosa succede all'interno del livello dati (database). Fondamentalmente, durante lo sviluppo avvio il profiler e controllo cosa generano alcune parti del codice in termini di query.

Se rilevo qualcosa di completamente complicato (ORM può generare terribili query anche da istruzioni LINQ piuttosto semplici, se non accuratamente scritte) e / o pesanti (durata, CPU, letture di pagine), lo prendo in SSMS e ne controllo il piano di esecuzione.

Funziona bene per il mio livello di conoscenza del database. Tuttavia, BULK INSERT sembra essere una creatura speciale, in quanto non sembra produrre uno SHOWPLAN .

Proverò a illustrare un esempio molto semplice:

Definizione della tabella

CREATE TABLE dbo.ImportingSystemFileLoadInfo
(
    ImportingSystemFileLoadInfoId INT NOT NULL IDENTITY(1, 1) CONSTRAINT PK_ImportingSystemFileLoadInfo PRIMARY KEY CLUSTERED,
    EnvironmentId INT NOT NULL CONSTRAINT FK_ImportingSystemFileLoadInfo REFERENCES dbo.Environment,
    ImportingSystemId INT NOT NULL CONSTRAINT FK_ImportingSystemFileLoadInfo_ImportingSystem REFERENCES dbo.ImportingSystem,
    FileName NVARCHAR(64) NOT NULL,
FileImportTime DATETIME2 NOT NULL,
    CONSTRAINT UQ_ImportingSystemImportInfo_EnvXIs_TableName UNIQUE (EnvironmentId, ImportingSystemId, FileName, FileImportTime)
)

Nota: nessun altro indice è definito nella tabella

L'inserto di massa (cosa catturo in profiler, un solo batch)

insert bulk [dbo].[ImportingSystemFileLoadInfo] ([EnvironmentId] Int, [ImportingSystemId] Int, [FileName] NVarChar(64) COLLATE Latin1_General_CI_AS, [FileImportTime] DateTime2(7))

Metrica

  • 695 articoli inseriti
  • CPU = 31
  • Legge = 4271
  • Scrive = 24
  • Durata = 154
  • Conteggio totale delle tabelle = 11500

Per la mia applicazione, va bene, anche se le letture sembrano piuttosto grandi (so molto poco sugli interni di SQL Server, quindi confrontando con la dimensione della pagina 8K e le informazioni sui piccoli record che ho)

Domanda: come posso verificare se questo BULK INSERT può essere ottimizzato? O non ha alcun senso, dal momento che è probabilmente il modo più veloce per trasferire grandi dati da un'applicazione client a SQL Server?

Risposte:


14

Per quanto posso dire, è possibile ottimizzare un inserto di massa in un modo molto simile che si ottimizzerebbe un inserto regolare. In genere, un piano di query per un semplice inserto non è molto informativo, quindi non preoccuparti di non avere il piano. Esaminerò alcuni modi per ottimizzare un inserto, ma la maggior parte di essi probabilmente non si applica all'inserto specificato nella domanda. Tuttavia, potrebbero essere utili se in futuro è necessario caricare grandi quantità di dati.

1. Inserire i dati nell'ordine delle chiavi del clustering

SQL Server ordinerà spesso i dati prima di inserirli in una tabella con un indice cluster. Per alcune tabelle e applicazioni è possibile migliorare le prestazioni ordinando i dati nel file flat e facendo sapere a SQL Server che i dati sono ordinati tramite l' ORDERargomento di BULK INSERT:

ORDINE ({colonna [ASC | DESC]} [, ... n])

Specifica come vengono ordinati i dati nel file di dati. Le prestazioni di importazione bulk vengono migliorate se i dati importati vengono ordinati in base all'indice cluster sulla tabella, se presente.

Dato che stai usando una IDENTITYcolonna come chiave cluster non devi preoccuparti di questo.

2. Utilizzare TABLOCKse possibile

Se hai la certezza di avere solo una sessione per inserire dati nella tabella, puoi specificare l' TABLOCKargomento per BULK INSERT. Ciò può ridurre la contesa tra i blocchi e può portare a una registrazione minima in alcuni scenari. Tuttavia, si sta inserendo in una tabella con un indice cluster che già contiene dati, quindi non si otterrà una registrazione minima senza il flag di traccia 610 che verrà menzionato più avanti in questa risposta.

Se TABLOCKnon è possibile, poiché non è possibile modificare il codice , non tutte le speranze vanno perse. Prendi in considerazione l'utilizzo di sp_table_option:

EXEC [sys].[sp_tableoption]
    @TableNamePattern = N'dbo.BulkLoadTable' ,
    @OptionName = 'table lock on bulk load' , 
    @OptionValue = 'ON'

Un'altra opzione è abilitare il flag di traccia 715 .

3. Utilizzare una dimensione del lotto appropriata

A volte sarai in grado di ottimizzare gli inserti modificando la dimensione del batch.

ROWS_PER_BATCH = rows_per_batch

Indica il numero approssimativo di righe di dati nel file di dati.

Per impostazione predefinita, tutti i dati nel file di dati vengono inviati al server come un'unica transazione e il numero di righe nel batch è sconosciuto a Query Optimizer. Se si specifica ROWS_PER_BATCH (con un valore> 0), il server utilizza questo valore per ottimizzare l'operazione di importazione in blocco. Il valore specificato per ROWS_PER_BATCH dovrebbe approssimativamente essere uguale al numero effettivo di righe. Per informazioni sulle considerazioni sulle prestazioni, consultare "Note" più avanti in questo argomento.

Ecco la citazione di seguito nell'articolo:

Se il numero di pagine da scaricare in un singolo batch supera una soglia interna, potrebbe verificarsi una scansione completa del pool di buffer per identificare le pagine da scaricare quando si esegue il commit del batch. Questa scansione completa può compromettere le prestazioni di importazione di massa. Un probabile caso di superamento della soglia interna si verifica quando un pool buffer di grandi dimensioni viene combinato con un sottosistema I / O lento. Per evitare overflow del buffer su macchine di grandi dimensioni, non utilizzare il suggerimento TABLOCK (che rimuoverà le ottimizzazioni di massa) o utilizzare una dimensione batch inferiore (che preserva le ottimizzazioni di massa).

Poiché i computer variano, ti consigliamo di testare varie dimensioni di batch con il caricamento dei dati per scoprire quale funziona meglio per te.

Personalmente vorrei solo inserire tutte le 695 righe in un singolo batch. L'ottimizzazione delle dimensioni del batch può fare una grande differenza quando si inseriscono molti dati.

4. Assicurati di aver bisogno della IDENTITYcolonna

Non so nulla del tuo modello di dati o requisiti, ma non cadere nella trappola dell'aggiunta di una IDENTITYcolonna a ogni tabella. Aaron Bertrand ha un articolo su questo chiamato Cattive abitudini da calciare: mettere una colonna IDENTITÀ su ogni tavolo . Per essere chiari, non sto dicendo che dovresti rimuovere la IDENTITYcolonna da questa tabella. Tuttavia, se si determina che la IDENTITYcolonna non è necessaria e la si rimuove, ciò potrebbe migliorare le prestazioni di inserimento.

5. Disabilitare indici o vincoli

Se stai caricando una grande quantità di dati in una tabella rispetto a quello che hai già, potrebbe essere più veloce disabilitare gli indici o i vincoli prima del caricamento e abilitarli dopo il caricamento. Per grandi quantità di dati, in genere è più inefficiente per SQL Server creare un indice tutto in una volta anziché quando i dati vengono caricati nella tabella. Sembra che tu abbia inserito 695 righe in una tabella con 11500 righe, quindi non consiglierei questa tecnica.

6. Considerare TF 610

Trace Flag 610 consente una registrazione minima in alcuni scenari aggiuntivi. Per la tua tabella con una IDENTITYchiave cluster, otterrai una registrazione minima per qualsiasi nuova pagina di dati purché il tuo modello di recupero sia semplice o registrato in blocco. Ritengo che questa funzione non sia attiva per impostazione predefinita perché potrebbe ridurre le prestazioni su alcuni sistemi. Dovresti testare attentamente prima di abilitare questo flag di traccia. Il riferimento Microsoft raccomandato sembra essere ancora la Guida alle prestazioni di caricamento dei dati

Impatto I / O della registrazione minima sotto la bandiera di traccia 610

Quando si esegue il commit di una transazione di caricamento di massa che è stata minimamente registrata, tutte le pagine caricate devono essere scaricate sul disco prima del completamento del commit. Qualsiasi pagina svuotata non catturata da un'operazione di checkpoint precedente può creare una grande quantità di I / O casuali. In contrasto con un'operazione completamente registrata, che crea invece I / O sequenziali nelle scritture del registro e non richiede che le pagine caricate vengano scaricate sul disco al momento del commit.

Se lo scenario di caricamento è costituito da piccole operazioni di inserimento su btrees che non attraversano i limiti del punto di arresto e si dispone di un sistema I / O lento, l'utilizzo della registrazione minima può effettivamente rallentare la velocità di inserimento.

Per quanto posso dire, questo non ha nulla a che fare con il flag di traccia 610, ma piuttosto con una registrazione minima. Credo che la precedente citazione ROWS_PER_BATCHsull'accordatura arrivasse a questo stesso concetto.

In conclusione, probabilmente non c'è molto che puoi fare per mettere a punto il tuo BULK INSERT. Non sarei preoccupato per il numero di letture che hai osservato con il tuo inserto. SQL Server segnalerà le letture ogni volta che si inseriscono dati. Considera quanto segue molto semplice INSERT:

DROP TABLE IF EXISTS X_TABLE;

CREATE TABLE X_TABLE (
VAL VARCHAR(1000) NOT NULL
);

SET STATISTICS IO, TIME ON;

INSERT INTO X_TABLE WITH (TABLOCK)
SELECT REPLICATE('Z', 1000)
FROM dbo.GetNums(10000); -- generate 10000 rows

Uscita da SET STATISTICS IO, TIME ON:

Tabella "X_TABLE". Conteggio scansione 0, letture logiche 11428

Ho 11428 letture riportate ma non si tratta di informazioni fruibili. A volte il numero di letture riportate può essere ridotto con una registrazione minima, ma ovviamente la differenza non può essere tradotta direttamente in un miglioramento delle prestazioni.


12

Inizierò a rispondere a questa domanda, con l'intenzione di aggiornare continuamente questa risposta mentre costruisco una base di conoscenze di trucchi. Spero che altri si imbattano in questo e mi aiutino a migliorare le mie conoscenze nel processo.

  1. Gut Check: il tuo firewall sta eseguendo un'ispezione approfondita dei pacchetti con stato? Non troverai molto su Internet a riguardo, ma se i tuoi inserti di massa sono circa 10 volte più lenti di quanto dovrebbero essere, è probabile che tu abbia un'appliance di sicurezza che esegue un'ispezione approfondita dei pacchetti di livello 3-7 e controlla "Prevenzione dell'iniezione SQL generica ".

  2. Misura la dimensione dei dati che prevedi di inserire in blocco, in byte, per batch. E controlla se stai memorizzando dati LOB, poiché si tratta di un'operazione di recupero e scrittura di pagine separate.

    Diversi motivi per cui dovresti farlo in questo modo:

    un. In AWS, gli IOPS di Elastic Block Storage vengono suddivisi in byte, non in righe.

    1. Consulta le prestazioni del volume Amazon EBS su istanze Linux »Caratteristiche I / O e monitoraggio per una spiegazione di cosa sia un'unità IOPS EBS
    2. In particolare, i volumi SSD per scopi generici (gp2) hanno il concetto di "crediti I / O e prestazioni di burst" ed è comune per l'elaborazione pesante di ETL esaurire i crediti di bilancio di burst. La durata del burst viene misurata in byte, non nelle righe di SQL Server :)

    b. Mentre la maggior parte delle biblioteche o dei white paper esegue il test in base al numero di righe, in realtà è il numero di pagine che possono essere scritte sull'argomento e, per calcolarlo, è necessario sapere quanti byte per riga e le dimensioni della pagina (in genere 8 KB , ma controlla sempre se hai ereditato il sistema da qualcun altro.)

    SELECT *
    FROM 
    sys.dm_db_index_physical_stats(DB_ID(),OBJECT_ID(N'YourTable'), NULL, NULL, 'DETAILED')

    Presta attenzione a avg_record_size_in_bytes e page_count.

    c. Come spiega Paul White in https://sqlperformance.com/2019/05/sql-performance/minimal-logging-insert-select-heap , "Per abilitare la registrazione minima con INSERT...SELECT, SQL Server deve aspettarsi più di 250 righe con una dimensione totale di almeno un'estensione (8 pagine). "

  3. Se si dispone di indici con vincoli di controllo o vincoli univoci, utilizzare SET STATISTICS IO ONe SET STATISTICS TIME ON(o SQL Server Profiler o SQL Server Extended Events) per acquisire informazioni come se l'inserto di massa abbia operazioni di lettura. Le operazioni di lettura sono dovute al motore di database di SQL Server che assicura il superamento dei vincoli di integrità.

  4. Prova a creare un database di prova in cui PRIMARYFILEGROUP è montato su un'unità RAM. Questo dovrebbe essere leggermente più veloce di SSD ma eliminare anche qualsiasi domanda sul fatto che il tuo controller RAID potrebbe aggiungere un sovraccarico. Nel 2018 non dovrebbe, ma creando più linee di base differenziali come questa, puoi avere un'idea generale di quanto sovraccarico sta aggiungendo il tuo hardware.

  5. Metti anche il file sorgente su un'unità RAM.

    Se si inserisce il file di origine su un'unità RAM, si escludono eventuali problemi di contesa se si sta leggendo il file di origine dalla stessa unità in cui si trova FILEGROUP del server di database.

  6. Verifica di aver formattato il disco rigido utilizzando le estensioni da 64 KB.

  7. Usa UserBenchmark.com e confronta il tuo SSD. Questo sarà:

    1. Aggiungi maggiori conoscenze ad altri appassionati di prestazioni su quali prestazioni aspettarsi da un dispositivo
    2. Aiutarti a capire se le prestazioni della tua unità sono peer performance inferiori con la stessa unità esatta
    3. Aiutarti a capire se le prestazioni del tuo disco sono inferiori a quelle di altre unità della stessa categoria (SSD, HDD, ecc.)
  8. Se stai chiamando "INSERT BULK" da C # tramite Entity Framework Extensions, assicurati di "riscaldare" prima il JIT e "gettare via" i primi risultati.

  9. Prova a creare contatori delle prestazioni per il tuo programma. Con .NET, puoi usare benchmark.NET e profilerà automaticamente un mucchio di metriche di base. È quindi possibile CONDIVIDERE i tentativi del profiler con la comunità open source e vedere se le persone che eseguono hardware diverso riportano le stesse metriche (vale a dire dal mio punto precedente sull'utilizzo di UserBenchmark.com per confrontare).

  10. Prova a utilizzare le pipe denominate ed eseguirlo come localhost.

  11. Se stai prendendo di mira SQL Server e stai utilizzando .NET Core, prendi in considerazione la possibilità di creare un Linux con SQL Server Std Edition: questo costa meno di un dollaro l'ora anche per hardware serio. Il vantaggio principale di provare lo stesso codice con lo stesso hardware con un sistema operativo diverso è vedere se lo stack TCP / IP del kernel del sistema operativo sta causando problemi.

  12. Utilizzare le query diagnostiche SQL Server di Glen Barry per misurare la latenza dell'unità per l'unità che memorizza FILEGROUP della tabella del database.

    un. Assicurati di misurare prima del test e dopo il test. Il "prima del test" ti dice se hai delle orribili caratteristiche IO come base.

    b. Per misurare "durante il test", è necessario utilizzare i contatori delle prestazioni PerfMon.

    Perché? Perché la maggior parte dei server di database utilizza una sorta di NAS (Network Attached Storage). Nel cloud, in AWS, Elastic Block Storage è proprio questo. Potresti essere vincolato dagli IOPS della tua soluzione volume / NAS EBS.

  13. Utilizzare alcuni strumenti per misurare le statistiche di attesa. Red Gate SQL Monitor , Analizzatore delle prestazioni del database SolarWinds o persino query diagnostiche SQL Server di Glen Barry o query statistiche di attesa di Paul Randal .

    un. I tipi di attesa più comuni saranno probabilmente Memory / CPU, WRITELOG, PAGEIOLATCH_EX e ASYNC_NETWORK_IO .

    b. Potresti incorrere in ulteriori tipi di attesa se esegui gruppi di disponibilità.

  14. Misura gli effetti di più INSERT BULKcomandi simultanei con TABLOCKdisabilitato (TABLOCK probabilmente forzerà la serializzazione dei comandi INSERT BULK). Il tuo collo di bottiglia potrebbe essere in attesa di un INSERT BULKcompletamento; dovresti provare a mettere in coda tutte queste attività quante sono in grado di gestire il modello di dati fisici del tuo server di database.

  15. Prendi in considerazione il partizionamento della tabella. Ad esempio: se la tabella del database è di sola aggiunta, Andrew Novick ha suggerito di creare un "OGGI" FILEGROUPe di partizionare in almeno due filegroup, OGGI e BEFORE_TODAY. In questo modo, se i tuoi INSERT BULKdati sono solo dati per oggi, puoi filtrare su un campo CreatedOn per forzare tutti gli inserti a colpire un singolo FILEGROUP, riducendo così il blocco durante l'utilizzo TABLOCK. Questa tecnica è descritta in modo più dettagliato in un white paper Microsoft: strategie di tabella e indici partizionate con SQL Server 2008

  16. Se si utilizzano gli indici columnstore, disattivare TABLOCKe caricare i dati in 102.400 righe Dimensione batch. È quindi possibile caricare tutti i dati in parallelo direttamente nei rowgroup di columnstore. Questo suggerimento (e documentato razionale) proviene dagli indici Columnstore di Microsoft - Guida al caricamento dei dati :

    Il caricamento in blocco ha queste ottimizzazioni delle prestazioni integrate:

    Carichi paralleli: è possibile avere più carichi in blocco simultanei (bcp o inserimento in blocco) che caricano ciascuno un file di dati separato. A differenza dei caricamenti collettivi di rowstore in SQL Server, non è necessario specificare TABLOCKperché ogni thread di importazione bulk caricherà i dati esclusivamente in un rowgroup separato (rowgroup compressi o delta) con blocco esclusivo su di esso. L'uso TABLOCKforzerà un blocco esclusivo sulla tabella e non sarà possibile importare i dati in parallelo.

    Registrazione minima:Un carico di massa utilizza una registrazione minima sui dati che vanno direttamente ai rowgroup compressi. Tutti i dati che vanno a un rowgroup delta sono completamente registrati. Ciò include qualsiasi dimensione batch inferiore a 102.400 righe. Tuttavia, con il caricamento di massa l'obiettivo è che la maggior parte dei dati ignori i rowgroup delta.

    Ottimizzazione del blocco: durante il caricamento nel rowgroup compresso, viene acquisito il blocco X sul rowgroup. Tuttavia, durante il caricamento di massa nel rowgroup delta, viene acquisito un blocco X nel rowgroup ma SQL Server blocca ancora i blocchi PAGE / EXTENT perché il blocco X rowgroup non fa parte della gerarchia dei blocchi.

  17. A partire da SQL Server 2016, non è più necessario abilitare il flag di traccia 610 per la registrazione minima nella tabella indicizzata . Citando l'ingegnere Microsoft Parikshit Savjani ( sottolineatura mia ):

    Uno degli obiettivi di progettazione di SQL Server 2016 era migliorare immediatamente le prestazioni e la scalabilità del motore per renderlo più veloce senza la necessità di manopole o flag di traccia per i clienti. Come parte di questi miglioramenti, uno dei miglioramenti apportati nel codice del motore di SQL Server è stato l'attivazione del contesto di caricamento in blocco (noto anche come inserimenti rapidi o contesto di caricamento rapido) e la registrazione minima per impostazione predefinita quando si eseguono operazioni di caricamento in blocco sul database con semplici o modello di recupero registrato in blocco. Se non si ha familiarità con la registrazione minima, consiglio vivamente di leggere questo post di Sunil Agrawal in cui spiega come funziona la registrazione minima in SQL Server. Affinché gli inserti di massa siano registrati in modo minimale, devono comunque soddisfare le condizioni preliminari che sono documentate qui.

    Come parte di questi miglioramenti in SQL Server 2016, non è più necessario abilitare il flag di traccia 610 per la registrazione minima nella tabella indicizzatae unisce alcune delle altre bandiere traccia (1118, 1117, 1236, 8048) per far parte della storia. In SQL Server 2016, quando l'operazione di caricamento di massa comporta l'assegnazione di una nuova pagina, tutte le righe che riempiono in sequenza quella nuova pagina vengono registrate in modo minimale se vengono soddisfatti tutti gli altri prerequisiti per la registrazione minima discussi in precedenza. Le righe inserite nelle pagine esistenti (nessuna nuova allocazione di pagine) per mantenere l'ordine dell'indice sono ancora completamente registrate, così come le righe che vengono spostate a seguito di suddivisioni di pagina durante il caricamento. È anche importante avere ALLOW_PAGE_LOCKS attivato per gli indici (che è ATTIVATO per impostazione predefinita) affinché l'operazione di registrazione minima funzioni mentre i blocchi di pagina vengono acquisiti durante l'allocazione e quindi vengono registrate solo le allocazioni di pagina o estensione.

  18. Se stai usando SqlBulkCopy in C # o EntityFramework.Extensions (che utilizza SqlBulkCopy sotto il cofano), controlla la tua configurazione di build. Stai eseguendo i test in modalità di rilascio? L'architettura di destinazione è impostata su Qualsiasi CPU / x64 / x86?

  19. Prendi in considerazione l'utilizzo di sp_who2 per vedere se la transazione INSERT BULK è SOSPESA. Potrebbe essere SOSPESO perché bloccato da un altro spid. Considera di leggere Come ridurre al minimo il blocco di SQL Server . Puoi anche usare sp_WhoIsActive di Adam Machanic, ma sp_who2 ti fornirà le informazioni di base di cui hai bisogno.

  20. Potresti avere solo I / O su disco difettoso. Se stai eseguendo un inserimento collettivo e l'utilizzo del disco non raggiunge il 100% e si blocca a circa il 2%, probabilmente hai un firmware difettoso o un dispositivo I / O difettoso. (Questo è successo a un mio collega.) Usa [SSD UserBenchmark] per confrontarlo con gli altri per le prestazioni dell'hardware, specialmente se puoi replicare la lentezza sulla tua macchina di sviluppo locale. (L'ho inserito per ultimo nell'elenco perché la maggior parte delle aziende non consente agli sviluppatori di eseguire database sul proprio computer locale a causa del rischio IP.)

  21. Se la tabella utilizza la compressione, puoi provare a eseguire più sessioni e, in ciascuna sessione, iniziare con l' utilizzo di una transazione esistente ed eseguirla prima del comando SqlBulkCopy:

    SET DI CONFIGURAZIONE ALTER SERVER AFFINITÀ PROCESSO CPU = AUTO;

  22. Per il caricamento continuo, un flusso di idee, delineato per la prima volta in un white paper di Microsoft, tabella partizionata e strategie di indice che utilizzano SQL Server 2008 :

    Caricamento continuo

    In uno scenario OLTP, i nuovi dati potrebbero arrivare continuamente. Se gli utenti eseguono anche query sulla partizione più recente, l'inserimento continuo di dati può comportare il blocco: le query degli utenti possono bloccare gli inserti e, allo stesso modo, gli inserimenti possono bloccare le query degli utenti.

    La contesa sulla tabella di caricamento o sulla partizione può essere ridotta utilizzando l'isolamento dello snapshot, in particolare il READ COMMITTED SNAPSHOTlivello di isolamento. Sotto READ COMMITTED SNAPSHOTisolamento, gli inserimenti in una tabella non causano attività nell'archivio versione tempdb , quindi l' overhead tempdb è minimo per gli inserimenti, ma nessun blocco condiviso verrà eseguito dalle query utente sulla stessa partizione.

    In altri casi, quando i dati vengono inseriti continuamente in una tabella partizionata a una velocità elevata, è possibile che sia ancora possibile posizionare i dati per brevi periodi di tempo nelle tabelle di gestione temporanea e quindi inserirli ripetutamente nella partizione più recente fino alla finestra per la partizione corrente passa e i dati vengono quindi inseriti nella partizione successiva. Ad esempio, supponiamo di avere due tabelle di gestione temporanea che ricevono dati di 30 secondi ciascuno, su base alternativa: una tabella per la prima metà di un minuto, la seconda tabella per la seconda metà di un minuto. Una procedura di inserimento memorizzata determina in quale metà del minuto si trova l'inserto corrente, quindi si inserisce nella prima tabella di gestione temporanea. Trascorsi 30 secondi, la procedura di inserimento determina che deve essere inserito nella seconda tabella di gestione temporanea. Un'altra procedura memorizzata carica quindi i dati dalla prima tabella di gestione temporanea nella partizione più recente della tabella e quindi tronca la prima tabella di gestione temporanea. Dopo altri 30 secondi, la stessa procedura memorizzata inserisce i dati dalla seconda procedura memorizzata e li inserisce nella partizione corrente, quindi tronca la seconda tabella di gestione temporanea.

  23. Guida alle prestazioni di caricamento dei dati del team Microsoft CAT

  24. Assicurati che le tue statistiche siano aggiornate. Usa FULLSCAN se puoi dopo ogni build dell'indice.

  25. SAN Performance Tuning con SQLIO e assicurati anche se stai utilizzando dischi meccanici che le tue partizioni del disco siano allineate. Consulta le best practice per l'allineamento delle partizioni del disco di Microsoft .

  26. COLUMNSTORE INSERT/ UPDATEperformance


2

È probabile che le letture siano i vincoli univoci e FK verificati durante l'inserimento: potresti ottenere un miglioramento della velocità se puoi disabilitarli / rilasciarli durante l'inserimento e abilitarli / ricrearli in seguito. Dovrai testare se questo rende tutto più lento rispetto a mantenerli attivi. Anche questa potrebbe non essere una buona idea se altri processi scrivono contemporaneamente sulla stessa tabella. - Gareth Lyons

Secondo le domande e risposte, le chiavi esterne diventano non attendibili dopo l'inserimento di massa , i vincoli FK non sono attendibili dopo un'opzione BULK INSERTsenza nessuna CHECK_CONSTRAINTS(il mio caso come ho terminato con vincoli non attendibili). Non è chiaro, ma non avrebbe senso controllarli e comunque renderli non attendibili. Tuttavia, PK e UNIQUE verranno comunque controllati (vedere BULK INSERT (Transact-SQL) ). - Alexei

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.