Database di esempio per OLTP in memoriaSample Database for In-Memory OLTP

PanoramicaOverview

Questo esempio illustra la funzionalità OLTP in memoria .This sample showcases the In-Memory OLTP feature. Mostra le tabelle con ottimizzazione per la memoria e le nuove stored procedure compilate in modo nativo, che possono essere usate per illustrare i vantaggi offerti da OLTP in memoria a livello di prestazioni.It shows memory-optimized tables and natively-compiled stored procedures, and can be used to demonstrate performance benefits of In-Memory OLTP.

Nota

Per visualizzare questo argomento per SQL Server 2014SQL Server 2014, vedere Estensioni a AdventureWorks per illustrare OLTP in memoria.To view this topic for SQL Server 2014SQL Server 2014, see Extensions to AdventureWorks to Demonstrate In-Memory OLTP.

Nell'esempio viene eseguita la migrazione di 5 tabelle del database AdventureWorks a tabelle con ottimizzazione per la memoria. Inoltre, è incluso un carico di lavoro dimostrativo di ordini vendita.The sample migrates 5 tables in the AdventureWorks database to memory-optimized, and it includes a demo workload for sales order processing. Questo carico di lavoro dimostrativo può essere usato per verificare i vantaggi a livello di prestazioni di OLTP in memoria nel server.You can use this demo workload to see the performance benefit of using In-Memory OLTP on your server.

La descrizione dell'esempio prende in esame i compromessi raggiunti quando si esegue la migrazione delle tabelle a OLTP in memoria per tenere conto delle funzionalità non (ancora) supportate per le tabelle con ottimizzazione per la memoria.In the description of the sample we discuss the tradeoffs that were made in migrating the tables to In-Memory OLTP to account for the features that are not (yet) supported for memory-optimized tables.

La documentazione di questo esempio è strutturata come segue:The documentation of this sample is structured as follows:

Prerequisites Prerequisites

Installing the In-Memory OLTP sample based on AdventureWorks Installing the In-Memory OLTP sample based on AdventureWorks

Per installare l'esempio, seguire i passaggi riportati di seguito.Follow these steps to install the sample:

  1. Scaricare AdventureWorks2016CTP3.bak e SQLServer2016CTP3Samples.zip da: https://www.microsoft.com/download/details.aspx?id=49502 a una cartella locale, ad esempio "c:\temp".Download AdventureWorks2016CTP3.bak and SQLServer2016CTP3Samples.zip from: https://www.microsoft.com/download/details.aspx?id=49502 to a local folder, for example 'c:\temp'.

  2. Ripristinare il backup del database usando Transact-SQLTransact-SQL o SQL Server Management StudioSQL Server Management Studio:Restore the database backup using Transact-SQLTransact-SQL or SQL Server Management StudioSQL Server Management Studio:

    1. Identificare la cartella di destinazione e il nome del file di dati, ad esempioIdentify the target folder and filename for the data file, for example

      'h:\DATA\AdventureWorks2016CTP3_Data.mdf''h:\DATA\AdventureWorks2016CTP3_Data.mdf'

    2. Identificare la cartella di destinazione e il nome del file di log, ad esempioIdentify the target folder and filename for the log file, for example

      'i:\DATA\AdventureWorks2016CTP3_log.ldf''i:\DATA\AdventureWorks2016CTP3_log.ldf'

      1. Il file di log deve essere posizionato in un'unità diversa dal file di dati, idealmente un'unità a bassa latenza, ad esempio l'archiviazione sull'unità SSD o PCIe, per prestazioni ottimali.The log file should be placed on a different drive than the data file, ideally a low latency drive such as an SSD or PCIe storage, for maximum performance.

      Script T-SQL di esempio:Example T-SQL script:

    RESTORE DATABASE [AdventureWorks2016CTP3]   
      FROM DISK = N'C:\temp\AdventureWorks2016CTP3.bak'   
        WITH FILE = 1,    
      MOVE N'AdventureWorks2016_Data' TO N'h:\DATA\AdventureWorks2016CTP3_Data.mdf',    
      MOVE N'AdventureWorks2016_Log' TO N'i:\DATA\AdventureWorks2016CTP3_log.ldf',  
      MOVE N'AdventureWorks2016CTP3_mod' TO N'h:\data\AdventureWorks2016CTP3_mod'  
     GO  
    
  3. Per visualizzare gli script e il carico di lavoro di esempio, decomprimere il file SQLServer2016CTP3Samples.zip in una cartella locale.To view the sample scripts and workload, unpack the file SQLServer2016CTP3Samples.zip to a local folder. Per istruzioni sull'esecuzione del carico di lavoro, consultare il file In-Memory OLTP\readme.txt.Consult the file In-Memory OLTP\readme.txt for instructions on running the workload.

Description of the sample tables and procedures Description of the sample tables and procedures

Nell'esempio vengono create nuove tabelle per i prodotti e gli ordini vendita, basate sulle tabelle esistenti in AdventureWorks.The sample creates new tables for products and sales orders, based on existing tables in AdventureWorks. Lo schema delle nuove tabelle è simile a quello delle tabelle esistenti, con alcune differenze, come illustrato di seguito.The schema of the new tables is similar to the existing tables, with a few differences, as explained below.

Nelle nuove tabelle con ottimizzazione per la memoria è incluso il suffisso "_inmem".The new memory-optimized tables carry the suffix ‘_inmem’. Nell'esempio, inoltre, sono incluse tabelle corrispondenti con il suffisso "_ondisk". Queste tabelle possono essere utilizzate per un confronto uno-a-uno tra le prestazioni delle tabelle con ottimizzazione per la memoria e quelle basate su disco nel sistema.The sample also includes corresponding tables carrying the suffix ‘_ondisk’ – these tables can be used to make a one-to-one comparison between the performance of memory-optimized tables and disk-based tables on your system..

Si noti che le tabelle con ottimizzazione per la memoria utilizzate nel carico di lavoro per il confronto delle prestazioni sono completamente durevoli e con registrazione completa.Note that the memory-optimized tables used in the workload for performance comparison are fully durable and fully logged. Con queste tabelle non viene sacrificata la durabilità o l'affidabilità per ottenere un miglioramento delle prestazioni.They do not sacrifice durability or reliability to attain the performance gain.

Il carico di lavoro di destinazione per questo esempio è rappresentato dall'elaborazione degli ordini vendita, in cui vengono prese in considerazione anche le informazioni sui prodotti e sugli sconti.The target workload for this sample is sales order processing, where we consider also information about products and discounts. A questo scopo, vengono utilizzate le tabelle SalesOrderHeader, SalesOrderDetail, Product, SpecialOffer e SpecialOfferProduct.To this end, the table SalesOrderHeader, SalesOrderDetail, Product, SpecialOffer, and SpecialOfferProduct.

Per inserire gli ordini vendita e aggiornare le informazioni sulla spedizione di un determinato ordine vendita vengono utilizzate due nuove stored procedure: Sales.usp_InsertSalesOrder_inmem e Sales.usp_UpdateSalesOrderShipInfo_inmem.Two new stored procedures, Sales.usp_InsertSalesOrder_inmem and Sales.usp_UpdateSalesOrderShipInfo_inmem, are used to insert sales orders and to update the shipping information of a given sales order.

Nel nuovo schema "Demo" sono incluse stored procedure e tabelle helper per eseguire un carico di lavoro dimostrativo.The new schema 'Demo' contains helper tables and stored procedures to execute a demo workload.

In concreto, nell'esempio di OLTP in memoria vengono aggiunti ad AdventureWorks gli oggetti seguenti:Concretely, the In-Memory OLTP sample adds the following objects to AdventureWorks:

Tabelle aggiunte con l'esempioTables added by the sample

Nuove tabelleThe New Tables

Sales.SalesOrderHeader_inmemSales.SalesOrderHeader_inmem

  • Informazioni di intestazione sugli ordini vendita.Header information about sales orders. Ogni ordine vendita è rappresentato da una riga nella tabella.Each sales order has one row in this table.

    Sales.SalesOrderDetail_inmemSales.SalesOrderDetail_inmem

  • Dettagli degli ordini vendita.Details of sales orders. Ogni voce di un ordine vendita è rappresentato da una riga nella tabella.Each line item of a sales order has one row in this table.

    Sales.SpecialOffer_inmemSales.SpecialOffer_inmem

  • Informazioni sulle offerte speciali, inclusa la percentuale di sconto associata a ogni offerta.Information about special offers, including the discount percentage associated with each special offer.

    Sales.SpecialOfferProduct_inmemSales.SpecialOfferProduct_inmem

  • Tabella di riferimento tra offerte speciali e prodotti.Reference table between special offers and products. Ogni offerta speciale può includere zero o più prodotti e ogni prodotto può essere caratterizzato da zero o più offerte speciali.Each special offer can feature zero or more products, and each product can be featured in zero or more special offers.

    Production.Product_inmemProduction.Product_inmem

  • Informazioni sui prodotti, tra cui il prezzo di listino.Information about products, including their list price.

    Demo.DemoSalesOrderDetailSeedDemo.DemoSalesOrderDetailSeed

  • Utilizzata nel carico di lavoro dimostrativo per creare ordini vendita di esempio.Used in the demo workload to construct sample sales orders.

    Varianti basate su disco delle tabelle:Disk-based variations of the tables:

  • Sales.SalesOrderHeader_ondiskSales.SalesOrderHeader_ondisk

  • Sales.SalesOrderDetail_ondiskSales.SalesOrderDetail_ondisk

  • Sales.SpecialOffer_ondiskSales.SpecialOffer_ondisk

  • Sales.SpecialOfferProduct_ondiskSales.SpecialOfferProduct_ondisk

  • Production.Product_ondiskProduction.Product_ondisk

Differenze tra le tabelle basate su disco originali e le nuove con ottimizzazione per la memoriaDifferences between original disk-based and the and new memory-optimized tables

In genere, nelle nuove tabelle introdotte con questo esempio vengono utilizzate le stesse colonne e gli stessi tipi di dati delle tabelle originali.For the most part, the new tables introduced by this sample use the same columns and the same data types as the original tables. Tuttavia, esistono alcune differenzeHowever, there are a few differences. elencate di seguito, insieme a una spiegazione logica delle modifiche.We list the differences below, along with a rationale for the changes.

Sales.SalesOrderHeader_inmemSales.SalesOrderHeader_inmem

  • Vincoli predefiniti . Sono supportati per le tabelle con ottimizzazione per la memoria; inoltre, la migrazione della maggior parte di questi vincoli è stata eseguita senza apportarvi variazioni.Default constraints are supported for memory-optimized tables, and most default constraints we migrated as is. Tuttavia, nella tabella originale Sales.SalesOrderHeader sono contenuti due vincoli predefiniti tramite cui viene recuperata la data corrente per le colonne OrderDate e ModifiedDate.However, the original table Sales.SalesOrderHeader contains two default constraints that retrieve the current date, for the columns OrderDate and ModifiedDate. In un carico di lavoro di elaborazione dell'ordine a velocità effettiva elevata con molta concorrenza, qualsiasi risorsa globale può diventare un punto di contesa.In a high throughput order processing workload with a lot of concurrency, any global resource can become a point of contention. L'ora di sistema è un esempio di risorsa globale e si è notato che può costituire un collo di bottiglia quando si esegue un carico di lavoro di OLTP in memoria con ordini vendita, in particolare se l'ora di sistema deve essere recuperata per più colonne nell'intestazione degli ordini di vendita, nonché per i dettagli degli ordini di vendita.System time is such a global resource, and we have observed that it can become a bottleneck when running an In-Memory OLTP workload that inserts sales orders, in particular if the system time needs to be retrieved for multiple columns in the sales order header, as well as the sales order details. In questo esempio il problema è stato risolto recuperando l'ora di sistema solo una volta per ogni ordine vendita inserito e il valore in questione viene utilizzato per le colonne di tipo datetime in SalesOrderHeader_inmem e in SalesOrderDetail_inmem, nella stored procedure Sales.usp_InsertSalesOrder_inmem.The problem is addressed in this sample by retrieving the system time only once for each sales order that is inserted, and use that value for the datetime columns in SalesOrderHeader_inmem and SalesOrderDetail_inmem, in the stored procedure Sales.usp_InsertSalesOrder_inmem.

  • Tipi definiti dall'utente (UDT) alias . Nella tabella originale sono utilizzati due tipi di dati alias definiti dall'utente (UDT), dbo.OrderNumber e dbo.AccountNumber, rispettivamente per le colonne PurchaseOrderNumber e AccountNumber.Alias UDTs - The original table uses two alias user-defined data types (UDTs) dbo.OrderNumber and dbo.AccountNumber, for the columns PurchaseOrderNumber and AccountNumber, respectively. SQL Server 2016SQL Server 2016 non supporta il tipo di dati alias definito dall'utente per le tabelle con ottimizzazione per la memoria, pertanto le nuove tabelle usano rispettivamente i tipi di dati di sistema nvarchar(25) e nvarchar(15). does not support alias UDT for memory-optimized tables, thus the new tables use system data types nvarchar(25) and nvarchar(15), respectively.

  • Colonne che ammettono i valori Null nelle chiavi di indice . Nella tabella originale la colonna SalesPersonID ammette i valori Null, mentre nelle nuove tabelle non ammette i valori Null e prevede un vincolo predefinito con valore (-1).Nullable columns in index keys - In the original table, the column SalesPersonID is nullable, while in the new tables the column is not nullable and has a default constraint with value (-1). Ciò è dovuto al fatto che gli indici nelle tabelle con ottimizzazione per la memoria non possono disporre di colonne che ammettono i valori Null nella chiave di indice; -1 è un surrogato di NULL in questo caso.This is because indexes on memory-optimized tables cannot have nullable columns in the index key; -1 is a surrogate for NULL in this case.

  • Colonne calcolate . Le colonne calcolate SalesOrderNumber e TotalDue vengono omesse, poiché in SQL Server 2016SQL Server 2016 non sono supportate colonne calcolate nelle tabelle con ottimizzazione per la memoria.Computed columns - The computed columns SalesOrderNumber and TotalDue are omitted, as SQL Server 2016SQL Server 2016 does not support computed columns in memory-optimized tables. La nuova vista Sales.vSalesOrderHeader_extended_inmem riflette le colonne SalesOrderNumber e TotalDue.The new view Sales.vSalesOrderHeader_extended_inmem reflects the columns SalesOrderNumber and TotalDue. Pertanto, può essere utilizzata qualora queste colonne fossero necessarie.Therefore, you can use this view if these columns are needed.

    • Applies to: SQL Server 2017SQL Server 2017 CTP 1.1.Applies to: SQL Server 2017SQL Server 2017 CTP 1.1.
      A partire da SQL Server 2017SQL Server 2017 CTP 1.1, le colonne calcolate sono supportate in indici e tabelle con ottimizzazione per la memoria.Beginning with SQL Server 2017SQL Server 2017 CTP 1.1, computed columns are supported in memory-optimized tables and indexes.
  • Insono supportati i vincoli di chiave esterna SQL Server 2016SQL Server 2016per le tabelle con ottimizzazione per la memoria, ma solo se anche le tabelle di riferimento sono dotate di ottimizzazione della memoria.Foreign key constraints are supported for memory-optimized tables in SQL Server 2016SQL Server 2016, but only if the referenced tables are also memory-optimized. Le chiavi esterne che fanno riferimento a tabelle migrate in altre tabelle con ottimizzazione della memoria sono mantenute nelle tabelle migrate, mentre le altre chiavi esterne vengono omesse.Foreign keys that reference tables that are also migrated to memory-optimized are kept in the migrated tables, while other foreign keys are omitted. Inoltre, SalesOrderHeader_inmem è una tabella attiva nel carico di lavoro di esempio e i vincoli di chiavi esterne comportano un'ulteriore elaborazione per tutte le operazioni DML, in quanto sono necessarie ricerche in tutte le altre tabelle a cui viene fatto riferimento in questi vincoli.In addition, SalesOrderHeader_inmem is a hot table in the example workload, and foreign keys constraints require additional processing for all DML operations, as it requires lookups in all the other tables referenced in these constraints. Pertanto, si presuppone che l'applicazione garantisca l'integrità referenziale per la tabella Sales.SalesOrderHeader_inmem e questa integrità non venga convalidata quando vengono inserite le righe.Therefore, the assumption is that the app ensures referential integrity for the Sales.SalesOrderHeader_inmem table, and referential integrity is not validated when rows are inserted.

  • Rowguid . La colonna rowguid viene omessa.Rowguid - The rowguid column is omitted. Anche se uniqueidentifier è il supporto per le tabelle con ottimizzazione per la memoria, l'opzione ROWGUIDCOL non è supportata in SQL Server 2016SQL Server 2016.While uniqueidentifier is support for memory-optimized tables, the option ROWGUIDCOL is not supported in SQL Server 2016SQL Server 2016. Le colonne di questo tipo vengono in genere utilizzate per la replica di tipo merge o per le tabelle con colonne FILESTREAM.Columns of this kind are typically used for either merge replication or tables that have filestream columns. Nell'esempio sono escluse entrambe.This sample includes neither.

    Sales.SalesOrderDetailSales.SalesOrderDetail

  • Vincoli predefiniti . Analogamente a SalesOrderHeader, non viene eseguita la migrazione del vincolo predefinito per cui sono richieste data/ora del sistema. L'inserimento della data/ora di sistema corrente verrà eseguito dalla stored procedure tramite cui vengono inseriti gli ordini di vendita al primo inserimento.Default constraints – similar to SalesOrderHeader, the default constraint requiring the system date/time is not migrated, instead the stored procedure inserting sales orders takes care of inserting the current system date/time on first insert.

  • Colonne calcolate . La migrazione della colonna calcolata LineTotal non è stata eseguita poiché le colonne di questo tipo non sono supportate con le tabelle con ottimizzazione per la memoria in SQL Server 2016SQL Server 2016.Computed columns – the computed column LineTotal was not migrated as computed columns are not supported with memory-optimized tables in SQL Server 2016SQL Server 2016. Per accedere a questa colonna, usare la vista Sales.vSalesOrderDetail_extended_inmem.To access this column use the view Sales.vSalesOrderDetail_extended_inmem.

  • Rowguid . La colonna rowguid viene omessa.Rowguid - The rowguid column is omitted. Per informazioni dettagliate, vedere la descrizione della tabella SalesOrderHeader.For details see the description for the table SalesOrderHeader.

    Production.ProductProduction.Product

  • Tipi alias definiti dall'utente (UDT) . Nella tabella originale viene utilizzato il tipo di dati definito dall'utente dbo.Flag, equivalente al bit del tipo di dati di sistema.Alias UDTs – the original table uses the user-defined data type dbo.Flag, which is equivalent to the system data type bit. Nella tabella migrata viene utilizzato, in alternativa, il tipo di dati bit.The migrated table uses the bit data type instead.

  • Rowguid . La colonna rowguid viene omessa.Rowguid - The rowguid column is omitted. Per informazioni dettagliate, vedere la descrizione della tabella SalesOrderHeader.For details see the description for the table SalesOrderHeader.

    Sales.SpecialOfferSales.SpecialOffer

  • Rowguid . La colonna rowguid viene omessa.Rowguid - The rowguid column is omitted. Per informazioni dettagliate, vedere la descrizione della tabella SalesOrderHeader.For details see the description for the table SalesOrderHeader.

    Sales.SpecialOfferProductSales.SpecialOfferProduct

  • Rowguid . La colonna rowguid viene omessa.Rowguid - The rowguid column is omitted. Per informazioni dettagliate, vedere la descrizione della tabella SalesOrderHeader.For details see the description for the table SalesOrderHeader.

Considerazioni sugli indici nelle tabelle con ottimizzazione per la memoriaConsiderations for indexes on memory-optimized tables

L'indice di base per le tabelle con ottimizzazione per la memoria è l'indice NONCLUSTERED, che supporta le ricerche di punti (ricerca nell'indice nel predicato di uguaglianza), le analisi dell'intervallo (ricerca nell'indice nel predicato di disuguaglianza), analisi di indici completi e analisi ordinate.The baseline index for memory-optimized tables is the NONCLUSTERED index, which supports point lookups (index seek on equality predicate), range scans (index seek in inequality predicate), full index scans, and ordered scans. Inoltre, gli indici NONCLUSTERED supportano la ricerca nelle colonne iniziali della chiave di indice.In addition, NONCLUSTERED indexes support searching on leading columns of the index key. In realtà, gli indici NONCLUSTERED con ottimizzazione per la memoria supportano tutte le operazioni consentite dagli indici NONCLUSTERED basati su disco, con la sola eccezione che vengono eseguite analisi a ritroso.In fact memory-optimized NONCLUSTERED indexes support all the operations supported by disk-based NONCLUSTERED indexes, with the only exception being backward scans. Pertanto, l'utilizzo di indici NONCLUSTERED è una scelta sicura.Therefore, using NONCLUSTERED indexes is a safe choice for your indexes.

Per ottimizzare ulteriormente il carico di lavoro, è possibile usare gli indici HASH.HASH indexes are can be used to further optimize the workload. Vengono ottimizzati in particolare per le ricerche di punti e per gli inserimenti di righe.They are particularly optimized for point lookups and row inserts. Tuttavia, è necessario considerare che non supportano le analisi dell'intervallo, le analisi ordinate o la ricerca nelle colonne iniziali della chiave di indice.However, one must consider that they do not support range scans, ordered scans, or search on leading index key columns. Di conseguenza, prestare attenzione quando si utilizzano questi indici.Therefore, care needs to be taken when using these indexes. Inoltre, è necessario specificare il bucket_count al momento della creazione.In addition, it is necessary to specify the bucket_count at create time. In genere deve essere impostato su un valore compreso tra una e due volte il numero di valori di chiave di indice; tuttavia, un valore superiore non rappresenta di solito un problema.It should usually be set at between one and two times the number of index key values, but overestimating is usually not a problem.

Vedere la documentazione online per altre informazioni sulle linee guida relative agli indici e sulle linee guida per scegliere il bucket_count corretto.See Books Online for more details about index guidelines and guidelines for choosing the right bucket_count.

Gli indici nelle tabelle migrate sono stati ottimizzati per il carico di lavoro dimostrativo dell'elaborazione degli ordini vendita.The indexes on the migrated tables have been tuned for the demo sales order processing workload. Il carico di lavoro si basa sugli inserimenti e sulle ricerche di punti nelle tabelle Sales.SalesOrderHeader_inmem e Sales.SalesOrderDetail_inmem, nonché sulle ricerche di punti nelle colonne chiavi primarie nelle tabelle Production.Product_inmem e Sales.SpecialOffer_inmem.The workload relies on inserts and point lookups in the tables Sales.SalesOrderHeader_inmem and Sales.SalesOrderDetail_inmem, and it also relies on point lookups on the primary key columns in the tables Production.Product_inmem and Sales.SpecialOffer_inmem.

Sales.SalesOrderHeader_inmem prevede tre indici, che sono tutti di tipo HASH per motivi di prestazioni e perché per il carico di lavoro non sono necessarie analisi ordinate, né dell'intervallo.Sales.SalesOrderHeader_inmem has three indexes, which are all HASH indexes for performance reasons, and because no ordered or range scans are needed for the workload.

  • Indice HASH in (SalesOrderID): il bucket_count viene ridimensionato a 10 milioni (arrotondato fino a 16 milione), poiché il numero previsto di ordini vendita è pari a 10 milioni.HASH index on (SalesOrderID): bucket_count is sized at 10 million (rounded up to 16 million), because the expected number of sales orders is 10 million

  • Indice HASH in (SalesPersonID): il bucket_count è pari a 1 milione.HASH index on (SalesPersonID): bucket_count is 1 million. Il set di dati specificato non dispone di molti venditori, ma tiene conto della crescita futura, nonché delle mancate conseguenze in termini di riduzione delle prestazioni per le ricerche di punti in caso di ridimensionamento eccessivo del bucket_count.The data set provided does not have a lot of sales persons, but this allows for future growth, plus you don’t pay a performance penalty for point lookups if the bucket_count is oversized.

  • Indice HASH in (CustomerID): il bucket_count è pari a 1 milione.HASH index on (CustomerID): bucket_count is 1 million. Il set di dati specificato non include molti clienti, ma tiene conto della crescita futura.The data set provided does not have a lot of customers, but this allows for future growth.

    Sales.SalesOrderDetail_inmem prevede tre indici, che sono tutti di tipo HASH per motivi di prestazioni e perché per il carico di lavoro non sono necessarie analisi ordinate, né dell'intervallo.Sales.SalesOrderDetail_inmem has three indexes, which are all HASH indexes for performance reasons, and because no ordered or range scans are needed for the workload.

  • Indice HASH in (SalesOrderID, SalesOrderDetailID): si tratta dell'indice di chiave primaria e, anche se le ricerche in (SalesOrderID, SalesOrderDetailID) saranno rare, l'utilizzo di un indice hash per la chiave rende più veloce gli inserimenti di riga.HASH index on (SalesOrderID, SalesOrderDetailID): this is the primary key index, and even though lookups on (SalesOrderID, SalesOrderDetailID) will be infrequent, using a hash index for the key speeds up row inserts. Il bucket_count viene ridimensionato a 50 milioni (arrotondato fino a 67 milioni); il numero previsto di ordini vendita è 10 milioni che viene ridimensionato per ottenere una media di 5 articoli per ordine.The bucket_count is sized at 50 million (rounded up to 67 million): the expected number of sales orders is 10 million, and this is sized to have an average of 5 items per order

  • Indice HASH in (SalesOrderID): le ricerche in base all'ordine vendita sono frequenti. È possibile individuare tutte le voci corrispondenti a un singolo ordine.HASH index on (SalesOrderID): lookups by sales order are frequent: you will want to find all the line items corresponding to a single order. Il bucket_count viene ridimensionato a 10 milioni (arrotondato fino a 16 milione), poiché il numero previsto di ordini vendita è pari a 10 milioni.bucket_count is sized at 10 million (rounded up to 16 million), because the expected number of sales orders is 10 million

  • Indice HASH in (ProductID): il bucket_count è pari a 1 milione.HASH index on (ProductID): bucket_count is 1 million. Il set di dati specificato non include molti prodotti, ma tiene conto della crescita futura.The data set provided does not have a lot of product, but this allows for future growth.

    Production.Product_inmem prevede tre indiciProduction.Product_inmem has three indexes

  • Indice HASH in (ProductID): le ricerche in ProductID si trovano in un percorso critico del carico di lavoro dimostrativo, pertanto si tratta di un indice hashHASH index on (ProductID): lookups on ProductID are in the critical path for the demo workload, therefore this is a hash index

  • Indice NONCLUSTERED in (Name): tramite esso saranno possibili analisi ordinate dei nomi dei prodottiNONCLUSTERED index on (Name): this will allow ordered scans of product names

  • Indice NONCLUSTERED in (ProductNumber): tramite esso saranno possibili analisi ordinate dei numeri dei prodottiNONCLUSTERED index on (ProductNumber): this will allow ordered scans of product numbers

    Sales.SpecialOffer_inmem con un indice HASH in (SpecialOfferID): le ricerche di punti delle offerte speciali si trovano nella parte essenziale del carico di lavoro dimostrativo.Sales.SpecialOffer_inmem has one HASH index on (SpecialOfferID): point lookups of special offers are in the critical part of the demo workload. Il bucket_count viene ridimensionato a 1 milione per tener conto della crescita futura.The bucket_count is sized at 1 million to allow for future growth.

    Nel carico di lavoro dimostrativo non viene fatto riferimento a Sales.SpecialOfferProduct_inmem, di conseguenza non vi sono esigenze apparenti di usare indici hash in questa tabella per ottimizzare il carico di lavoro; gli indici in (SpecialOfferID, ProductID) e (ProductID) sono NONCLUSTERED.Sales.SpecialOfferProduct_inmem is not referenced in the demo workload, and thus there is no apparent need to use hash indexes on this table to optimize the workload – the indexes on (SpecialOfferID, ProductID) and (ProductID) are NONCLUSTERED.

    Si noti che nelle indicazioni sopra riportate, ad alcuni dei bucket_counts è stato applicato un ridimensionamento eccessivo, ma non ai bucket_counts per gli indici in SalesOrderHeader_inmem e SalesOrderDetail_inmem che vengono ridimensionati solo a 10 milioni di ordini vendita.Notice that in the above some of the bucket_counts are over-sized, but not the bucket_counts for the indexes on SalesOrderHeader_inmem and SalesOrderDetail_inmem: they are sized for just 10 million sales orders. Questa operazione viene eseguita per consentire l'installazione dell'esempio nei sistemi con disponibilità di memoria insufficiente, anche se in quei casi il carico di lavoro dimostrativo non può essere completato.This was done to allow installing the sample on systems with low memory availability, although in those cases the demo workload will fail with out-of-memory. Se si desidera scalare di oltre 10 milioni di ordini vendita, è possibile aumentare i numeri di bucket di conseguenza.If you do want to scale well beyond 10 million sales orders, feel free to increase the bucket counts accordingly.

Considerazioni sull'utilizzo della memoriaConsiderations for memory utilization

L'utilizzo della memoria nel database di esempio, sia prima che dopo l'esecuzione del carico di lavoro dimostrativo, è descritto nella sezione Utilizzo della memoria per le tabelle con ottimizzazione per la memoria.Memory utilization in the sample database, both before and after running the demo workload, is discussed in the Section Memory utilization for the memory-optimized tables.

Stored procedure aggiunte nell'esempioStored Procedures added by the sample

Di seguito sono riportate due stored procedure principali per l'inserimento dell'ordine vendita e l'aggiornamento dei dettagli sulla spedizione:The two key stored procedures for inserting sales order and updating shipping details are as follows:

  • Sales.usp_InsertSalesOrder_inmemSales.usp_InsertSalesOrder_inmem

    • Inserisce un nuovo ordine vendita nel database e restituisce SalesOrderID per questi ordini vendita.Inserts a new sales order in the database and outputs the SalesOrderID for that sales order. Come parametri di input accetta i dettagli dell'intestazione dell'ordine vendita e le voci dell'ordine.As input parameters it takes details for the sales order header, as well as the line items in the order.

    • Parametro di output:Output parameter:

      • @SalesOrderID int. SalesOrderID per l'ordine vendita appena inserito@SalesOrderID int – the SalesOrderID for the sales order that was just inserted
    • Parametri di input (obbligatori):Input parameters (required):

      • @DueDate datetime2@DueDate datetime2

      • @CustomerID int@CustomerID int

      • @BillToAddressID [int]@BillToAddressID [int]

      • @ShipToAddressID [int]@ShipToAddressID [int]

      • @ShipMethodID [int]@ShipMethodID [int]

      • @SalesOrderDetails Sales.SalesOrderDetailType_inmem. TVP contenente voci dell'ordine@SalesOrderDetails Sales.SalesOrderDetailType_inmem – TVP that contains the line items of the order

    • Parametri di input (facoltativi):Input parameters (optional):

      • @Status [tinyint]@Status [tinyint]

      • @OnlineOrderFlag [bit]@OnlineOrderFlag [bit]

      • @PurchaseOrderNumber [nvarchar](25)@PurchaseOrderNumber [nvarchar](25)

      • @AccountNumber [nvarchar](15)@AccountNumber [nvarchar](15)

      • @SalesPersonID [int]@SalesPersonID [int]

      • @TerritoryID [int]@TerritoryID [int]

      • @CreditCardID [int]@CreditCardID [int]

      • @CreditCardApprovalCode [varchar](15)@CreditCardApprovalCode [varchar](15)

      • @CurrencyRateID [int]@CurrencyRateID [int]

      • @Comment nvarchar(128)@Comment nvarchar(128)

  • Sales.usp_UpdateSalesOrderShipInfo_inmemSales.usp_UpdateSalesOrderShipInfo_inmem

    • Aggiornare le informazioni sulla spedizione per un ordine vendita specificato.Update the shipping information for a given sales order. Verranno aggiornate anche le informazioni sulla spedizione di tutte le voci dell'ordine vendita.This will also update the shipping information for all line items of the sales order.

    • Si tratta di una stored procedure wrapper per le stored procedure compilate a livello nativo Sales.usp_UpdateSalesOrderShipInfo_native con logica di riesecuzione per gestire i potenziali (imprevisti) conflitti con transazioni simultanee con cui viene aggiornato lo stesso ordine.This is a wrapper procedure for the natively compiled stored procedures Sales.usp_UpdateSalesOrderShipInfo_native with retry logic to deal with (unexpected) potential conflicts with concurrent transactions updating the same order. Per altre informazioni sulla logica di riesecuzione, vedere l'argomento nella documentazione online qui.For more information about retry logic see the Books Online topic here.

  • Sales.usp_UpdateSalesOrderShipInfo_nativeSales.usp_UpdateSalesOrderShipInfo_native

    • Si tratta della stored procedure compilata a livello nativo tramite cui viene elaborato effettivamente l'aggiornamento delle informazioni sulla spedizione.This is the natively compiled stored procedure that actually processes the update to the shipping information. Ciò significa che viene chiamata dalla stored procedure wrapper Sales.usp_UpdateSalesOrderShipInfo_inmem.It is means to be called from the wrapper stored procedure Sales.usp_UpdateSalesOrderShipInfo_inmem. Se tramite il client è possibile gestire gli errori e implementare la logica di riesecuzione, è possibile chiamare direttamente questa procedura, anziché usare quella wrapper.If the client can deal with failures and implements retry logic, you can call this procedure directly, rather than using the wrapper stored procedure.

    La stored procedure seguente viene utilizzata per il carico di lavoro dimostrativo.The following stored procedure is used for the demo workload.

  • Demo.usp_DemoResetDemo.usp_DemoReset

    • Reimposta la dimostrazione svuotando e reinizializzando le tabelle SalesOrderHeader e SalesOrderDetail.Resets the demo by emptying and reseeding the SalesOrderHeader and SalesOrderDetail tables.

    Le stored procedure seguenti vengono utilizzate per l'inserimento nelle tabelle con ottimizzazione per la memoria ed eliminazione da queste ultime garantendo, nel contempo, le integrità di dominio e referenziale.The following stored procedures are used for inserting in and deleting from memory-optimized tables while guaranteeing domain and referential integrity.

  • Production.usp_InsertProduct_inmemProduction.usp_InsertProduct_inmem

  • Production.usp_DeleteProduct_inmemProduction.usp_DeleteProduct_inmem

  • Sales.usp_InsertSpecialOffer_inmemSales.usp_InsertSpecialOffer_inmem

  • Sales.usp_DeleteSpecialOffer_inmemSales.usp_DeleteSpecialOffer_inmem

  • Sales.usp_InsertSpecialOfferProduct_inmemSales.usp_InsertSpecialOfferProduct_inmem

    Infine, la stored procedure seguente viene utilizzata per verificare le integrità di dominio e referenziale.Finally the following stored procedure is used to verify domain and referential integrity.

  1. dbo.usp_ValidateIntegritydbo.usp_ValidateIntegrity

    • Parametro facoltativo: @object_id . ID dell'oggetto per cui convalidare l'integritàOptional parameter: @object_id – ID of the object to validate integrity for

    • Questa procedura si basa sulle tabelle dbo.DomainIntegrity, dbo.ReferentialIntegrity e dbo.UniqueIntegrity per le regole di integrità che devono essere verificate. Nell'esempio queste tabelle vengono popolate in base ai vincoli CHECK, di chiave esterna e univoci presenti per le tabelle originali nel database AdventureWorks.This procedure relies on the tables dbo.DomainIntegrity, dbo.ReferentialIntegrity, and dbo.UniqueIntegrity for the integrity rules that need to be verified – the sample populates these tables based on the check, foreign key, and unique constraints that exist for the original tables in the AdventureWorks database.

    • Si basa sulle procedure helper dbo.usp_GenerateCKCheck, dbo.usp_GenerateFKCheck e dbo.GenerateUQCheck per generare il codice T-SQL necessario per eseguire i controlli di integrità.It relies on the helper procedures dbo.usp_GenerateCKCheck, dbo.usp_GenerateFKCheck, and dbo.GenerateUQCheck to generate the T-SQL needed for performing the integrity checks.

Performance Measurements using the Demo Workload Performance Measurements using the Demo Workload

Ostress è uno strumento da riga di comando sviluppato dal team di supporto Microsoft CSS SQL Server .Ostress is a command-line tool that was developed by the Microsoft CSS SQL Server support team. Questo strumento può essere utilizzato per eseguire query o stored procedure in parallelo.This tool can be used to execute queries or run stored procedures in parallel. È possibile configurare il numero di thread per eseguire un'istruzione T-SQL fornita in parallelo e specificare il numero di esecuzioni dell'istruzione in questo thread. Tramite ostress viene eseguita l'accelerazione dei thread e l'istruzione viene eseguita in tutti i thread in parallelo.You can configure the number of threads to run a given T-SQL statement in parallel, and you can specify how many times the statement should be executed on this thread; ostress will spin up the threads and execute the statement on all threads in parallel. Al termine dell'esecuzione di tutti i thread, tramite ostress verrà segnalato il tempo impiegato per il completamento dell'esecuzione di tutti i thread.After execution finishes for all threads, ostress will report the time taken for all threads to finish execution.

Installazione di ostressInstalling ostress

Ostress viene installato come parte delle utilità RML. La relativa installazione non viene eseguita in modalità autonoma.Ostress is installed as part of the RML Utilities; there is no standalone installation for ostress.

Passaggi dell'installazione:Installation steps:

  1. Scaricare ed eseguire il pacchetto di installazione x64 per le utilità RML dalla pagina seguente: http://blogs.msdn.com/b/psssql/archive/2013/10/29/cumulative-update-2-to-the-rml-utilities-for-microsoft-sql-server-released.aspxDownload and run the x64 installation package for the RML utilities from the following page: http://blogs.msdn.com/b/psssql/archive/2013/10/29/cumulative-update-2-to-the-rml-utilities-for-microsoft-sql-server-released.aspx

  2. Se viene visualizzata una finestra di dialogo indicante l'utilizzo di determinati file, scegliere "Continua".If there is a dialog box saying certain files are in use, click ‘Continue’

Esecuzione di ostressRunning ostress

Ostress viene eseguito dal prompt della riga di comando.Ostress is run from the command-line prompt. È più semplice eseguire lo strumento dal prompt dei comandi RML, installato come parte delle utilità RML.It is most convenient to run the tool from the "RML Cmd Prompt", which is installed as part of the RML Utilities.

Per aprire il prompt dei comandi RML, seguire queste istruzioni:To open the RML Cmd Prompt follow these instructions:

In Windows Server 2012 [R2] e in Windows 8 e 8.1 aprire il menu Start facendo clic sul pulsante Windows, quindi digitare "rml".In Windows Server 2012 [R2] and in Windows 8 and 8.1, open the start menu by clicking the Windows key, and type ‘rml’. Fare clic sul prompt dei comandi RML, che sarà disponibile nell'elenco dei risultati della ricerca.Click on “RML Cmd Prompt”, which will be in the list of search results.

Verificare che il prompt dei comandi si trovi nella cartella di installazione delle utilità RML.Ensure that the command prompt is located in the RML Utilities installation folder.

Le opzioni della riga di comando per ostress possono essere visualizzate eseguendo semplicemente ostress.exe senza opzioni della riga di comando.The command-line options for ostress can be seen when simply running ostress.exe without any command-line options. Le opzioni principali da considerare per eseguire ostress con questo esempio sono:The main options to consider for running ostress with this sample are:

  • -S. Nome dell'istanza di SQL Server a cui connettersi-S name of Microsoft SQL Server instance to connect to

  • -E. Usare l'autenticazione di Windows per la connessione (valore predefinito); se si usa l'autenticazione di SQL Server , usare le opzioni –U e –P per specificare rispettivamente il nome utente e la password-E use Windows authentication to connect (default); if you use SQL Server authentication, use the options –U and –P to specify the username and password, respectively

  • -d. Nome del database, per questo esempio AdventureWorks2014-d name of the database, for this example AdventureWorks2014

  • -Q. L'istruzione T-SQL da eseguire-Q the T-SQL statement to be executed

  • -n. Numero di connessioni tramite cui viene eseguita l'elaborazione di ogni query o file di input-n number of connections processing each input file/query

  • -r. Numero di iterazioni per ogni connessione per eseguire ogni query o file di input-r the number of iterations for each connection to execute each input file/query

Carico di lavoro dimostrativoDemo Workload

La stored procedure principale utilizzata nel carico di lavoro dimostrativo è Sales.usp_InsertSalesOrder_inmem/ondisk.The main stored procedure used in the demo workload is Sales.usp_InsertSalesOrder_inmem/ondisk. Tramite lo script riportato di seguito viene costruito un parametro con valori di tabella (TVP) con dati di esempio e viene chiamata la procedura per inserire un ordine vendita con 5 voci.The script in the below constructs a table-valued parameter (TVP) with sample data, and calls the procedure to insert a sales order with 5 line items.

Lo strumento ostress viene utilizzato per eseguire le chiamate di stored procedure in parallelo, per simulare i client tramite cui vengono inseriti contemporaneamente gli ordini vendita.The ostress tool is used to execute the stored procedure calls in parallel, to simulate clients inserting sales orders concurrently.

Reimpostare la dimostrazione dopo ogni esecuzione di test di stress eseguendo Demo.usp_DemoReset.Reset the demo after each stress run executing Demo.usp_DemoReset. Tramite questa procedura vengono eliminate le righe nelle tabelle con ottimizzazione per la memoria, vengono troncate le tabelle basate su disco e viene eseguito un checkpoint del database.This procedure deletes the rows in the memory-optimized tables, truncates the disk-based tables, and executes a database checkpoint.

Lo script seguente viene eseguito simultaneamente per simulare un carico di lavoro di elaborazione degli ordini vendita:The following script is executed concurrently to simulate a sales order processing workload:

DECLARE   
      @i int = 0,   
      @od Sales.SalesOrderDetailType_inmem,   
      @SalesOrderID int,   
      @DueDate datetime2 = sysdatetime(),   
      @CustomerID int = rand() * 8000,   
      @BillToAddressID int = rand() * 10000,   
      @ShipToAddressID int = rand() * 10000,   
      @ShipMethodID int = (rand() * 5) + 1;   

INSERT INTO @od   
SELECT OrderQty, ProductID, SpecialOfferID   
FROM Demo.DemoSalesOrderDetailSeed   
WHERE OrderID= cast((rand()*106) + 1 as int);   

WHILE (@i < 20)   
BEGIN;   
      EXEC Sales.usp_InsertSalesOrder_inmem @SalesOrderID OUTPUT, @DueDate, @CustomerID, @BillToAddressID, @ShipToAddressID, @ShipMethodID, @od;   
      SET @i += 1   
END  

Con questo script, ogni ordine di esempio creato viene inserito 20 volte, tramite 20 stored procedure eseguite in un ciclo WHILE.With this script, each sample order that is constructed is inserted 20 times, through 20 stored procedures executed in a WHILE loop. Il ciclo viene utilizzato per rappresentare il fatto che il database viene utilizzato per creare l'ordine di esempio.The loop is used to account for the fact that the database is used to construct the sample order. Negli ambienti di produzione tipici, tramite l'applicazione di livello intermedio verrà costruito l'ordine vendita da inserire.In typical production environments, the mid-tier application will construct the sales order to be inserted.

Tramite lo script precedente gli ordini vendita vengono inseriti nelle tabelle con ottimizzazione per la memoria.The above script inserts sales orders into memory-optimized tables. Lo script per inserire gli ordini vendita nelle tabelle basate su disco deriva dalla sostituzione di due occorrenze di "_inmem" con "_ondisk".The script to insert sales orders into disk-based tables is derived by replacing the two occurrences of ‘_inmem’ with ‘_ondisk’.

Si utilizzerà lo strumento ostress per eseguire gli script utilizzando diverse connessioni simultanee.We will use the ostress tool to execute the scripts using several concurrent connections. Si utilizzerà il parametro "-n" per controllare il numero di connessioni e il parametro "r" per controllare il numero di volte in cui lo script viene eseguito in ogni connessione.We will use the parameter ‘-n’ to control the number of connections, and the parameter ‘r’ to control how many times the script is executed on each connection.

Esecuzione del carico di lavoroRunning the Workload

Per testare una scala vengono inseriti 10 milioni di ordini vendita, utilizzando 100 connessioni.To test at scale we insert 10 million sales orders, using 100 connections. Questo test viene eseguito ragionevolmente in un server modesto, ad esempio con 8 core fisici e 16 logici, e un'archiviazione sull'unità SSD di base per il log.This test performs reasonably on a modest server (e.g., 8 physical, 16 logical cores), and basic SSD storage for the log. Se il test non viene eseguito correttamente nell'hardware, consultare la sezione Risoluzione dei problemi relativi ai test con esecuzione prolungata. Se si desidera ridurre il livello di stress per questo test, ridurre il numero di connessioni modificando il parametro "-n".If the test does not perform well on your hardware, take look at the Section Troubleshooting slow-running tests.If you want to reduce the level of stress for this test, lower the number of connections by changing the parameter ‘-n’. Ad esempio, per abbassare il numero di connessioni a 40, impostare il parametro "-n100" su "-n40".For example to lower the connection count to 40, change the parameter ‘-n100’ to ‘-n40’.

Come misura delle prestazioni del carico di lavoro è possibile usare il tempo trascorso come riportato da ostress.exe dopo l'esecuzione del carico di lavoro.As a performance measure for the workload we use the elapsed time as reported by ostress.exe after running the workload.

Le istruzioni e le misure seguenti usano un carico di lavoro che inserisce 10 milioni di ordini di vendita.The below instructions and measurements use a workload that inserts 10 million sales orders. Per le istruzioni su come eseguire un carico di lavoro in scala ridotta inserendo 1 milione di ordini di vendita, vedere le istruzioni in "In-Memory OLTP\readme.txt" che fa parte dell'archivio SQLServer2016CTP3Samples.zip.For instructions to run a scaled-down workload inserting 1 million sales orders, see the instructions in 'In-Memory OLTP\readme.txt' that is part of the SQLServer2016CTP3Samples.zip archive.

Tabelle con ottimizzazione per la memoriaMemory-optimized tables

Si inizierà eseguendo il carico di lavoro nelle tabelle con ottimizzazione per la memoria.We will start by running the workload on memory-optimized tables. Tramite il comando seguente vengono aperti 100 thread, ognuno in esecuzione per 5.000 iterazioni.The following command opens 100 threads, each running for 5,000 iterations. Tramite ogni iterazione vengono inseriti 20 ordini vendita in transazioni separate.Each iteration inserts 20 sales orders in separate transactions. Vi sono 20 inserimenti per ogni iterazione per compensare il fatto che il database viene utilizzato per generare i dati da inserire.There are 20 inserts per iteration to compensate for the fact that the database is used to generate the data to be inserted. Ciò produce un totale pari a 20 * 5.000 * 100 = 10.000.000 di inserimenti di ordini vendita.This yield a total of 20 * 5,000 * 100 = 10,000,000 sales order inserts.

Aprire il prompt dei comandi RML ed eseguire il comando riportato di seguito:Open the RML Cmd Prompt, and execute the following command:

Fare clic sul pulsante Copia per copiare il comando e incollarlo nel prompt dei comandi delle utilità RML.Click the Copy button to copy the command, and paste it into the RML Utilities command prompt.

ostress.exe –n100 –r5000 -S. -E -dAdventureWorks2016CTP3 -q -Q"DECLARE @i int = 0, @od Sales.SalesOrderDetailType_inmem, @SalesOrderID int, @DueDate datetime2 = sysdatetime(), @CustomerID int = rand() * 8000, @BillToAddressID int = rand() * 10000, @ShipToAddressID int = rand() * 10000, @ShipMethodID int = (rand() * 5) + 1; INSERT INTO @od SELECT OrderQty, ProductID, SpecialOfferID FROM Demo.DemoSalesOrderDetailSeed WHERE OrderID= cast((rand()*106) + 1 as int); while (@i < 20) begin; EXEC Sales.usp_InsertSalesOrder_inmem @SalesOrderID OUTPUT, @DueDate, @CustomerID, @BillToAddressID, @ShipToAddressID, @ShipMethodID, @od; set @i += 1 end"  

In un server di test con un numero totale di 8 core fisici (16 logici), l'operazione ha richiesto 2 minuti e 5 secondi.On one test server with a total number of 8 physical (16 logical) cores, this took 2 minutes and 5 seconds. In un secondo server di prova con 24 core fisici (48 logici), l'operazione ha richiesto 1 minuto e 0 secondi.On a second test server with 24 physical (48 logical) cores, this took 1 minute and 0 seconds.

Osservare l'utilizzo della CPU mentre il carico di lavoro è in esecuzione, ad esempio tramite Gestione attività.Observe the CPU utilization while the workload is running, for example using task manager. Si noterà che l'utilizzo della CPU è vicino al 100%.You will see that CPU utilization is close to 100%. In caso contrario, si avrà un collo di bottiglia a livello di operazioni di I/O del log. Vedere anche Risoluzione dei problemi relativi ai test con esecuzione prolungata.If this is not the case, you have a log IO bottleneck see also Troubleshooting slow-running tests.

Tabelle basate su discoDisk-based tables

Tramite il comando riportato di seguito verrà eseguito il carico di lavoro nelle tabelle basate su disco.The following command will run the workload on disk-based tables. Si noti che l'esecuzione di questo carico di lavoro può richiedere del tempo, in gran parte a causa di una contesa di latch nel sistema.Note that this workload may take a while to execute, which is largely due to latch contention in the system. Le tabelle con ottimizzazione per la memoria sono prive di latch e pertanto prive di questo problema.Memory-optimized table are latch-free and thus do not suffer from this problem.

Aprire il prompt dei comandi RML ed eseguire il comando riportato di seguito:Open the RML Cmd Prompt, and execute the following command:

Fare clic sul pulsante Copia per copiare il comando e incollarlo nel prompt dei comandi delle utilità RML.Click the Copy button to copy the command, and paste it into the RML Utilities command prompt.

ostress.exe –n100 –r5000 -S. -E -dAdventureWorks2016CTP3 -q -Q"DECLARE @i int = 0, @od Sales.SalesOrderDetailType_ondisk, @SalesOrderID int, @DueDate datetime2 = sysdatetime(), @CustomerID int = rand() * 8000, @BillToAddressID int = rand() * 10000, @ShipToAddressID int = rand() * 10000, @ShipMethodID int = (rand() * 5) + 1; INSERT INTO @od SELECT OrderQty, ProductID, SpecialOfferID FROM Demo.DemoSalesOrderDetailSeed WHERE OrderID= cast((rand()*106) + 1 as int); while (@i < 20) begin; EXEC Sales.usp_InsertSalesOrder_ondisk @SalesOrderID OUTPUT, @DueDate, @CustomerID, @BillToAddressID, @ShipToAddressID, @ShipMethodID, @od; set @i += 1 end"  

In un server di prova con un numero totale di 8 core fisici (16 logici), l'operazione ha richiesto 41 minuti e 25 secondi.On one test server with a total number of 8 physical (16 logical) cores, this took 41 minutes and 25 seconds. In un secondo server di prova con 24 core fisici (48 logici), l'operazione ha richiesto 52 minuti e 16 secondi.On a second test server with 24 physical (48 logical) cores, this took 52 minutes and 16 seconds.

Il fattore principale della differenza a livello di prestazioni tra le tabelle con ottimizzazione per la memoria e quelle basate su disco in questo test è che quando si usano le tabelle basate su disco, SQL Server non può usare completamente la CPU.The main factor in the performance difference between memory-optimized tables and disk-based tables in this test is the fact that when using disk-based tables, SQL Server cannot not fully utilize the CPU. Il motivo è la contesa di latch: tramite le transazioni simultanee si tenta di scrivere nella stessa pagina di dati; i latch vengono utilizzati per garantire che in una pagina venga scritta una sola transazione per volta.The reason is latch contention: concurrent transactions are attempting to write to the same data page; latches are used to ensure only one transaction at a time can write to a page. Il motore di OLTP in memoria è privo di latch e le righe di dati non sono organizzate in pagine.The In-Memory OLTP engine is latch-free, and data rows are not organized in pages. Di conseguenza, le transazioni simultanee non impediscono inserimenti reciproci, consentendo in questo modo l'uso completo della CPU da parte di SQL Server.Thus, concurrent transactions do not block each other’s inserts, thus enabling SQL Server to fully utilize the CPU.

È possibile osservare l'utilizzo della CPU mentre il carico di lavoro è in esecuzione, ad esempio tramite Gestione attività.You can observe the CPU utilization while the workload is running, for example using task manager. Si noterà che con le tabelle basate su disco l'utilizzo della CPU è lontano dal 100%.You will see with disk-based tables the CPU utilization is far from 100%. In una configurazione di prova con 16 processori logici, l'utilizzo si aggira intorno al 24%.On a test configuration with 16 logical processors, the utilization would hover around 24%.

Facoltativamente, è possibile visualizzare il numero di attese di latch al secondo tramite Performance Monitor, con il contatore delle prestazioni "\SQL Server:Latches\Latch Waits/sec".Optionally, you can view the number of latch waits per second using Performance Monitor, with the performance counter ‘\SQL Server:Latches\Latch Waits/sec’.

Reimpostazione della dimostrazioneResetting the demo

Per reimpostare la dimostrazione, aprire il prompt dei comandi RML ed eseguire il comando riportato di seguito:To reset the demo, open the RML Cmd Prompt, and execute the following command:

ostress.exe -S. -E -dAdventureWorks2016CTP3 -Q"EXEC Demo.usp_DemoReset"  

A seconda dell'hardware, l'esecuzione può richiedere alcuni minuti.Depending on the hardware this may take a few minutes to run.

Si consiglia una reimpostazione dopo ogni esecuzione della dimostrazione.We recommend a reset after every demo run. Poiché questo carico di lavoro è caratterizzato solo da operazioni di inserimento, per ogni esecuzione verrà utilizzata più memoria e, pertanto, per impedire l'esaurimento di quest'ultima sarà necessario eseguire una reimpostazione.Because this workload is insert-only, each run will consume more memory, and thus a reset is required to prevent running out of memory. La quantità di memoria utilizzata dopo un'esecuzione è descritta nella sezione Utilizzo della memoria dopo l'esecuzione del carico di lavoro.The amount of memory consumed after a run is discussed in Section Memory utilization after running the workload.

Troubleshooting slow-running tests Troubleshooting slow-running tests

I risultati dei test variano in genere a seconda dell'hardware e del livello di concorrenza utilizzato durante l'esecuzione del test.Test results will typically vary with hardware, and also the level of concurrency used in the test run. Se i risultati non sono quelli previsti, è opportuno verificare alcune informazioni:A couple of things to look for if the results are not as expected:

  • Numero di transazioni simultanee. Quando si esegue il carico di lavoro in un solo thread, il miglioramento delle prestazioni con OLTP in memoria sarà probabilmente minore di 2 volte.Number of concurrent transactions: When running the workload on a single thread, performance gain with In-Memory OLTP will likely be less than 2X. La contesa di latch è un grande problema solo se vi è un livello elevato di concorrenza.Latch contention is only a big problem if there is a high level of concurrency.

  • Numero contenuto di core disponibili in SQL Server. Ciò significa che vi sarà un livello basso di concorrenza nel sistema, dal momento che vi possono essere tante esecuzioni simultanee di transazioni quanti sono i core disponibili in SQL.Low number of cores available to SQL Server: This means there will be a low level of concurrency in the system, as there can only be as many concurrently executing transactions as there are cores available to SQL.

    • Sintomo: se l'utilizzo della CPU è elevato durante l'esecuzione del carico di lavoro nelle tabelle basate su disco, ciò significa che non vi sono molte contese, puntando a una mancanza di concorrenza.Symptom: if the CPU utilization is high when running the workload on disk-based tables, this means there is not a lot of contention, pointing to a lack of concurrency.
  • Velocità dell'unità dei log: se l'unità dei log non resta sincronizzata con il livello di velocità effettiva delle transazioni nel sistema, il carico di lavoro diventa un collo di bottiglia nelle operazioni di I/O del log.Speed of the log drive: If the log drive cannot keep up with the level of transaction throughput in the system, the workload becomes bottlenecked on log IO. Sebbene la registrazione sia più efficiente con OLTP in memoria, se le operazioni di I/O del log rappresentano un collo di bottiglia, il potenziale miglioramento delle prestazioni sarà limitato.Although logging is more efficient with In-Memory OLTP, if log IO is a bottleneck, the potential performance gain is limited.

    • Sintomo: se l'utilizzo della CPU non è vicino al 100% o presenta molti problemi durante l'esecuzione del carico di lavoro nelle tabelle con ottimizzazione per la memoria, è possibile la presenza di un collo di bottiglia a livello di I/O del log.Symptom: if the CPU utilization is not close to 100% or is very spiky when running the workload on memory-optimized tables, it is possible there is a log IO bottleneck. Questa situazione può essere verificata aprendo il monitoraggio risorse ed esaminando la lunghezza della coda per l'unità dei log.This can be confirmed by opening Resource Monitor and looking at the queue length for the log drive.

Utilizzo della memoria e dello spazio su disco nell'esempio Memory and Disk Space Utilization in the Sample

Di seguito viene descritto cosa ci si aspetta in termini di utilizzo della memoria e dello spazio su disco per il database di esempio.In the below we describe what to expect in terms of memory and disk space utilization for the sample database. Vengono inoltre illustrati i risultati ottenuti in un server di prova con 16 core logici.We also show the results we have seen in on a test server with 16 logical cores.

Memory utilization for the memory-optimized tables Memory utilization for the memory-optimized tables

Utilizzo complessivo del databaseOverall utilization of the database

La query seguente può essere usata per ottenere l'utilizzo totale della memoria per OLTP in memoria nel sistema.The following query can be used to obtain the total memory utilization for In-Memory OLTP in the system.

SELECT type  
   , name  
, pages_kb/1024 AS pages_MB   
FROM sys.dm_os_memory_clerks WHERE type LIKE '%xtp%'  

Snapshot dopo aver appena creato il database:Snapshot after the database has just been created:

typetype namename pages_MBpages_MB
MEMORYCLERK_XTPMEMORYCLERK_XTP DefaultDefault 9494
MEMORYCLERK_XTPMEMORYCLERK_XTP DB_ID_5DB_ID_5 877877
MEMORYCLERK_XTPMEMORYCLERK_XTP DefaultDefault 00
MEMORYCLERK_XTPMEMORYCLERK_XTP DefaultDefault 00

I clerk di memoria predefiniti contengono strutture di memoria di sistema e sono relativamente ridotti.The default memory clerks contain system-wide memory structures and are relatively small. Il clerk di memoria per il database utente, in questo caso il database con ID 5, è pari a circa 900 MB.The memory clerk for the user database, in this case database with ID 5, is about 900MB.

Utilizzo della memoria per ogni tabellaMemory utilization per table

La query seguente può essere utilizzata per eseguire il drill-down nell'utilizzo della memoria delle singole tabelle e dei relativi indici:The following query can be used to drill down into the memory utilization of the individual tables and their indexes:

SELECT object_name(t.object_id) AS [Table Name]  
     , memory_allocated_for_table_kb  
 , memory_allocated_for_indexes_kb  
FROM sys.dm_db_xtp_table_memory_stats dms JOIN sys.tables t   
ON dms.object_id=t.object_id  
WHERE t.type='U'  

Di seguito vengono mostrati i risultati di questa query per un'installazione aggiornata dell'esempio:The following shows the results of this query for a fresh installation of the sample:

Nome tabellaTable Name memory_allocated_for_table_kbmemory_allocated_for_table_kb memory_allocated_for_indexes_kbmemory_allocated_for_indexes_kb
SpecialOfferProduct_inmemSpecialOfferProduct_inmem 6464 38403840
DemoSalesOrderHeaderSeedDemoSalesOrderHeaderSeed 19841984 55045504
SalesOrderDetail_inmemSalesOrderDetail_inmem 1531615316 663552663552
DemoSalesOrderDetailSeedDemoSalesOrderDetailSeed 6464 1043210432
SpecialOffer_inmemSpecialOffer_inmem 33 81928192
SalesOrderHeader_inmemSalesOrderHeader_inmem 71687168 147456147456
Product_inmemProduct_inmem 124124 1235212352

Come si può notare, le dimensioni delle tabelle sono piuttosto piccole: SalesOrderHeader_inmem è di circa 7 MB e SalesOrderDetail_inmem di circa 15 MB.As you can see the tables are fairly small: SalesOrderHeader_inmem is about 7MB, and SalesOrderDetail_inmem is about 15MB in size.

Ciò che colpisce qui sono le dimensioni della memoria allocata per gli indici, rispetto alle dimensioni dei dati della tabella.What is striking here is the size of the memory allocated for indexes, compared to the size of the table data. Questa condizione è dovuta al fatto che gli indici hash nell'esempio vengono ridimensionati preventivamente per una dimensione più ampia dei dati.That is because the hash indexes in the sample are pre-sized for a larger data size. Si noti che gli indici hash hanno dimensioni fisse e pertanto non aumenteranno con le dimensioni dei dati nella tabella.Note that hash indexes have a fixed size, and thus their size will not grow with the size of data in the table.

Memory utilization after running the workload Memory utilization after running the workload

Dopo l'inserimento di 10 milioni di ordini vendita, l'aspetto dell'utilizzo di tutta la memoria è simile a quanto riportato di seguito:After insert 10 million sales orders, the all-up memory utilization looks similar to the following:

SELECT type  
, name  
, pages_kb/1024 AS pages_MB   
FROM sys.dm_os_memory_clerks WHERE type LIKE '%xtp%'  
typetype namename pages_MBpages_MB
MEMORYCLERK_XTPMEMORYCLERK_XTP DefaultDefault 146146
MEMORYCLERK_XTPMEMORYCLERK_XTP DB_ID_5DB_ID_5 73747374
MEMORYCLERK_XTPMEMORYCLERK_XTP DefaultDefault 00
MEMORYCLERK_XTPMEMORYCLERK_XTP DefaultDefault 00

Come si può notare, SQL Server usa un bit in 8 GB per gli indici e le tabelle con ottimizzazione per la memoria nel database di esempio.As you can see, SQL Server is using a bit under 8GB for the memory-optimized tables and indexes in the sample database.

Esaminare l'utilizzo dettagliato della memoria per tabella dopo un'esecuzione di esempio:Looking at the detailed memory usage per table after one example run:

SELECT object_name(t.object_id) AS [Table Name]  
     , memory_allocated_for_table_kb  
 , memory_allocated_for_indexes_kb  
FROM sys.dm_db_xtp_table_memory_stats dms JOIN sys.tables t   
ON dms.object_id=t.object_id  
WHERE t.type='U'  
Nome tabellaTable Name memory_allocated_for_table_kbmemory_allocated_for_table_kb memory_allocated_for_indexes_kbmemory_allocated_for_indexes_kb
SalesOrderDetail_inmemSalesOrderDetail_inmem 51137615113761 663552663552
DemoSalesOrderDetailSeedDemoSalesOrderDetailSeed 6464 1036810368
SpecialOffer_inmemSpecialOffer_inmem 22 81928192
SalesOrderHeader_inmemSalesOrderHeader_inmem 15756791575679 147456147456
Product_inmemProduct_inmem 111111 1203212032
SpecialOfferProduct_inmemSpecialOfferProduct_inmem 6464 37123712
DemoSalesOrderHeaderSeedDemoSalesOrderHeaderSeed 19841984 55045504

Si può notare un totale pari a circa 6,5 GB di dati.We can see a total of about 6.5GB of data. Si noti che le dimensioni degli indici delle tabelle SalesOrderHeader_inmem e SalesOrderDetail_inmem equivalgono alle dimensioni degli indici prima dell'inserimento degli ordini vendita.Notice that the size of the indexes on the table SalesOrderHeader_inmem and SalesOrderDetail_inmem is is the same as the size of the indexes before inserting the sales orders. Le dimensioni dell'indice non sono state modificate perché in entrambe le tabelle vengono utilizzati indici hash e questo tipo di indice è statico.The index size did not change because both tables are using hash indexes, and hash indexes are static.

Dopo la reimpostazione della dimostrazioneAfter demo reset

La stored procedure Demo.usp_DemoReset può essere utilizzata per reimpostare la dimostrazione.The stored procedure Demo.usp_DemoReset can be used to reset the demo. Tramite essa vengono eliminati i dati nelle tabelle SalesOrderHeader_inmem e SalesOrderDetail_inmem e vengono reinizializzati i dati dalle tabelle originali SalesOrderHeader e SalesOrderDetail.It deletes the data in the tables SalesOrderHeader_inmem and SalesOrderDetail_inmem, and re-seeds the data from the original tables SalesOrderHeader and SalesOrderDetail.

A questo punto, anche se le righe nelle tabelle sono state eliminate, questo non significa che la memoria venga recuperata immediatamente.Now, even though the rows in the tables have been deleted, this does not mean that memory is reclaimed immediately. SQL Server recupera memoria in background dalle righe eliminate nelle tabelle con ottimizzazione per la memoria, in base alle esigenze.SQL Server reclaims memory from deleted rows in memory-optimized tables in the background, as needed. Si noterà che subito dopo la reimpostazione della dimostrazione, senza il carico di lavoro transazionale nel sistema, la memoria non è ancora stata recuperata dalle righe eliminate:You will see that immediately after demo reset, with no transactional workload on the system, memory from deleted rows is not yet reclaimed:

SELECT type  
, name  
, pages_kb/1024 AS pages_MB   
FROM sys.dm_os_memory_clerks WHERE type LIKE '%xtp%'  
typetype namename pages_MBpages_MB
MEMORYCLERK_XTPMEMORYCLERK_XTP DefaultDefault 22612261
MEMORYCLERK_XTPMEMORYCLERK_XTP DB_ID_5DB_ID_5 73967396
MEMORYCLERK_XTPMEMORYCLERK_XTP DefaultDefault 00
MEMORYCLERK_XTPMEMORYCLERK_XTP DefaultDefault 00

Si prevede che la memoria verrà recuperata quando il carico di lavoro transazionale è in esecuzione.This is expected: memory will be reclaimed when the transactional workload is running.

Se si avvia una seconda esecuzione del carico di lavoro dimostrativo, si noterà inizialmente una diminuzione dell'utilizzo della memoria, dal momento che le righe eliminate in precedenza vengono rimosse.If you start a second run of the demo workload you will see the memory utilization decrease initially, as the previously deleted rows are cleaned up. A un certo punto le dimensioni della memoria aumenteranno di nuovo, finché il carico di lavoro non viene completato.At some point the memory size will increase again, until the workload finishes. Dopo l'inserimento di 10 milioni di righe al termine della reimpostazione della dimostrazione, l'utilizzo della memoria sarà molto simile all'utilizzo dopo la prima esecuzione.After inserting 10 million rows after demo reset, the memory utilization will be very similar to the utilization after the first run. Esempio:For example:

SELECT type  
, name  
, pages_kb/1024 AS pages_MB   
FROM sys.dm_os_memory_clerks WHERE type LIKE '%xtp%'  
typetype namename pages_MBpages_MB
MEMORYCLERK_XTPMEMORYCLERK_XTP DefaultDefault 18631863
MEMORYCLERK_XTPMEMORYCLERK_XTP DB_ID_5DB_ID_5 73907390
MEMORYCLERK_XTPMEMORYCLERK_XTP DefaultDefault 00
MEMORYCLERK_XTPMEMORYCLERK_XTP DefaultDefault 00

Utilizzo del disco per tabelle con ottimizzazione per la memoriaDisk utilization for memory-optimized tables

Le dimensioni complessive su disco per i file del checkpoint di un database in un determinato momento possono essere recuperate tramite la query seguente:The overall on-disk size for the checkpoint files of a database at a given time can be found using the query:

SELECT SUM(df.size) * 8 / 1024 AS [On-disk size in MB]  
FROM sys.filegroups f JOIN sys.database_files df   
   ON f.data_space_id=df.data_space_id  
WHERE f.type=N'FX'  

Stato inizialeInitial state

Quando vengono creati inizialmente il filegroup di esempio e le tabelle con ottimizzazione per la memoria di esempio, vengono creati preventivamente un numero di file del checkpoint e, tramite il sistema viene iniziata la compilazione di questi file. Il numero di file del checkpoint creati in precedenza dipende dal numero di processori logici nel sistema.When the sample filegroup and sample memory-optimized tables are created initially, a number of checkpoint files are pre-created and the system starts filling the files – the number of checkpoint files pre-created depends on the number of logical processors in the system. Poiché l'esempio è inizialmente contenuto, i file creati in precedenza saranno per la maggior parte vuoti al termine della creazione iniziale.As the sample is initially very small, the pre-created files will be mostly empty after initial create.

Di seguito vengono mostrate le dimensioni iniziali su disco per l'esempio in un computer con 16 processori logici:The following shows the initial on-disk size for the sample on a machine with 16 logical processors:

SELECT SUM(df.size) * 8 / 1024 AS [On-disk size in MB]  
FROM sys.filegroups f JOIN sys.database_files df   
   ON f.data_space_id=df.data_space_id  
WHERE f.type=N'FX'  

||
|-|
|On-disk size in MBOn-disk size in MB|
|23122312|

Come si può notare, esiste una grande discrepanza tra le dimensioni su disco dei file del checkpoint, vale a dire 2,3 GB, e le dimensioni effettive dei dati, prossime a 30 MB.As you can see, there is a big discrepancy between the on-disk size of the checkpoint files, which is 2.3GB, and the actual data size, which is closer to 30MB.

Esaminando più da vicino la provenienza dell'utilizzo dello spazio su disco, è possibile usare la query indicata di seguito.Looking closer at where the disk-space utilization comes from, you can use the following query. La dimensione su disco restituita dalla query è approssimativa per i file con lo stato in 5 (REQUIRED FOR BACKUP/HA), 6 (IN TRANSITION TO TOMBSTONE) o 7 (TOMBSTONE).The size on disk returned by this query is approximate for files with state in 5 (REQUIRED FOR BACKUP/HA), 6 (IN TRANSITION TO TOMBSTONE), or 7 (TOMBSTONE).

SELECT state_desc  
 , file_type_desc  
 , COUNT(*) AS [count]  
 , SUM(CASE  
   WHEN state = 5 AND file_type=0 THEN 128*1024*1024  
   WHEN state = 5 AND file_type=1 THEN 8*1024*1024  
   WHEN state IN (6,7) THEN 68*1024*1024  
   ELSE file_size_in_bytes  
    END) / 1024 / 1024 AS [on-disk size MB]   
FROM sys.dm_db_xtp_checkpoint_files  
GROUP BY state, state_desc, file_type, file_type_desc  
ORDER BY state, file_type  

Per lo stato iniziale dell'esempio, il risultato sarà simile per un server con 16 processori logici:For the initial state of the sample, the result will look something like for a server with 16 logical processors:

state_descstate_desc file_type_descfile_type_desc countcount on-disk size MBon-disk size MB
PRECREATEDPRECREATED DATADATA 1616 20482048
PRECREATEDPRECREATED DELTADELTA 1616 128128
UNDER CONSTRUCTIONUNDER CONSTRUCTION DATADATA 11 128128
UNDER CONSTRUCTIONUNDER CONSTRUCTION DELTADELTA 11 88

Come si può notare, la maggior parte dello spazio è utilizzato dai file differenziali e di dati creati in precedenza.As you can see, most of the space is used by precreated data and delta files. SQL Server ha creato preventivamente una coppia di file (differenziali e di dati) per processore logico.SQL Server pre-created one pair of (data, delta) files per logical processor. Inoltre, i file di dati vengono ridimensionati preventivamente a 128 MB mentre quelli differenziali a 8 MB, per poter consentire un inserimento di dati in questi file più efficiente.In addition, data files are pre-sized at 128MB, and delta files at 8MB, in order to make inserting data into these files more efficient.

I dati effettivi nelle tabelle con ottimizzazione per la memoria si trovano nel singolo file di dati.The actual data in the memory-optimized tables is in the single data file.

Dopo l'esecuzione del carico di lavoroAfter running the workload

Dopo una singola esecuzione di test tramite cui vengono inseriti 10 milioni di ordini vendita, le dimensioni complessive su disco saranno simili alle seguenti (per un server di prova con 16 core):After a single test run that inserts 10 million sales orders, the overall on-disk size looks something like this (for a 16-core test server):

SELECT SUM(df.size) * 8 / 1024 AS [On-disk size in MB]  
FROM sys.filegroups f JOIN sys.database_files df   
   ON f.data_space_id=df.data_space_id  
WHERE f.type=N'FX'  

||
|-|
|On-disk size in MBOn-disk size in MB|
|88288828|

Le dimensioni su disco sono prossime ai 9 GB, che sono simili a quelle delle dimensioni in memoria dei dati.The on-disk size is close to 9GB, which comes close to the in-memory size of the data.

Esaminando più da vicino le dimensioni dei file del checkpoint nei vari stati:Looking more closely at the sizes of the checkpoint files across the various states:

SELECT state_desc  
 , file_type_desc  
 , COUNT(*) AS [count]  
 , SUM(CASE  
   WHEN state = 5 AND file_type=0 THEN 128*1024*1024  
   WHEN state = 5 AND file_type=1 THEN 8*1024*1024  
   WHEN state IN (6,7) THEN 68*1024*1024  
   ELSE file_size_in_bytes  
    END) / 1024 / 1024 AS [on-disk size MB]   
FROM sys.dm_db_xtp_checkpoint_files  
GROUP BY state, state_desc, file_type, file_type_desc  
ORDER BY state, file_type  
state_descstate_desc file_type_descfile_type_desc countcount on-disk size MBon-disk size MB
PRECREATEDPRECREATED DATADATA 1616 20482048
PRECREATEDPRECREATED DELTADELTA 1616 128128
UNDER CONSTRUCTIONUNDER CONSTRUCTION DATADATA 11 128128
UNDER CONSTRUCTIONUNDER CONSTRUCTION DELTADELTA 11 88

Si dispone ancora di 16 coppie di file creati in precedenza, pronti all'utilizzo alla chiusura dei checkpoint.We still have 16 pairs of pre-created files, ready to go as checkpoints are closed.

È disponibile una coppia in fase di costruzione, che viene utilizzata fino a quando il checkpoint corrente non viene chiuso.There is one pair under construction, which is used until the current checkpoint is closed. Insieme ai file del checkpoint attivi, questa coppia offre circa 6,5 GB di utilizzo su disco per 6,5 GB di dati in memoria.Along with the active checkpoint files this gives about 6.5GB of disk utilization for 6.5GB of data in memory. Si tenta presente che gli indici non vengono salvati in modo persistente su disco e pertanto, in questo caso, le dimensioni complessive su disco sono inferiori rispetto a quelle in memoria.Recall that indexes are not persisted on disk, and thus the overall size on disk is smaller than the size in memory in this case.

Dopo la reimpostazione della dimostrazioneAfter demo reset

Dopo la reimpostazione della dimostrazione, lo spazio su disco non viene recuperato immediatamente se non vi è un carico di lavoro transazionale nel sistema e non vi sono checkpoint del database.After demo reset, disk space is not reclaimed immediately if there is no transactional workload on the system, and there are not database checkpoints. Per i file del checkpoint da spostare nelle varie fasi e infine da rimuovere, devono verificarsi diversi checkpoint ed eventi di troncamento del log, per avviare l'unione dei file del checkpoint, nonché il processo di Garbage Collection.For checkpoint files to be moved through their various stages and eventually be discarded, a number of checkpoints and log truncation events need to happen, to initiate merge of checkpoint files, as well as to initiate garbage collection. Ciò si verifica automaticamente se si dispone di un carico di lavoro transazionale nel sistema, e vengono eseguiti backup regolari del log, qualora venga utilizzato il modello di recupero con registrazione completa, ma non quando il sistema è inattivo, come in uno scenario dimostrativo.These will happen automatically if you have a transactional workload in the system [and take regular log backups, in case you are using the FULL recovery model], but not when the system is idle, as in a demo scenario.

Nell'esempio, dopo la reimpostazione della dimostrazione, è possibile che si ottenga un risultato simile al seguenteIn the example, after demo reset, you may see something like

SELECT SUM(df.size) * 8 / 1024 AS [On-disk size in MB]  
FROM sys.filegroups f JOIN sys.database_files df   
   ON f.data_space_id=df.data_space_id  
WHERE f.type=N'FX'  

||
|-|
|On-disk size in MBOn-disk size in MB|
|1183911839|

Quasi 12 GB, che sono significativamente maggiori dei 9 GB disponibili prima della reimpostazione della dimostrazione.At nearly 12GB, this is significantly more than the 9GB we had before the demo reset. Ciò è dovuto al fatto che sono state avviate alcune operazioni di unione di file del checkpoint, ma alcune destinazioni delle unioni non sono ancora state installate e alcuni dei file di origine di unione non sono ancora stati rimossi, come si può notare da quanto riportato di seguito:This is because some checkpoint file merges have been started, but some of the merge targets have not yet been installed, and some of the merge source files have not yet been cleaned up, as can be seen from the following:

SELECT state_desc  
 , file_type_desc  
 , COUNT(*) AS [count]  
 , SUM(CASE  
   WHEN state = 5 AND file_type=0 THEN 128*1024*1024  
   WHEN state = 5 AND file_type=1 THEN 8*1024*1024  
   WHEN state IN (6,7) THEN 68*1024*1024  
   ELSE file_size_in_bytes  
    END) / 1024 / 1024 AS [on-disk size MB]   
FROM sys.dm_db_xtp_checkpoint_files  
GROUP BY state, state_desc, file_type, file_type_desc  
ORDER BY state, file_type  
state_descstate_desc file_type_descfile_type_desc countcount on-disk size MBon-disk size MB
PRECREATEDPRECREATED DATADATA 1616 20482048
PRECREATEDPRECREATED DELTADELTA 1616 128128
ACTIVEACTIVE DATADATA 3838 51525152
ACTIVEACTIVE DELTADELTA 3838 13311331
MERGE TARGETMERGE TARGET DATADATA 77 896896
MERGE TARGETMERGE TARGET DELTADELTA 77 5656
MERGED SOURCEMERGED SOURCE DATADATA 1313 17721772
MERGED SOURCEMERGED SOURCE DELTADELTA 1313 455455

Le destinazioni delle unioni vengono installate e le origini unite vengono rimosse quando viene eseguita l'attività transazionale nel sistema.Merge targets are installed and merged source are cleaned up as transactional activity happens in the system.

Al termine di una seconda esecuzione del carico di lavoro dimostrativo, inserendo 10 milioni di ordini vendita dopo la reimpostazione della dimostrazione, si noterà che i file creati durante la prima esecuzione del carico di lavoro sono stati rimossi.After a second run of the demo workload, inserting 10 million sales orders after the demo reset, you will see that the files constructed during the first run of the workload have been cleaned up. Se si esegue la query sopra indicata più volte durante l'esecuzione del carico di lavoro, si potranno visualizzare i file del checkpoint durante le varie fasi.If you run the above query several times while the workload is running, you can see the checkpoint files make their way through the various stages.

Dopo la seconda esecuzione del carico di lavoro con l'inserimento di 10 milioni di ordini vendita, si visualizzerà un utilizzo del disco molto simile a (ma non necessariamente lo stesso di quello dopo la prima esecuzione) quello del sistema dinamico in natura.After the second run of the workload insert 10 million sales orders you will see disk utilization very similar to, though not necessarily the same as after the first run, as the system is dynamic in nature. Esempio:For example:

SELECT state_desc  
 , file_type_desc  
 , COUNT(*) AS [count]  
 , SUM(CASE  
   WHEN state = 5 AND file_type=0 THEN 128*1024*1024  
   WHEN state = 5 AND file_type=1 THEN 8*1024*1024  
   WHEN state IN (6,7) THEN 68*1024*1024  
   ELSE file_size_in_bytes  
    END) / 1024 / 1024 AS [on-disk size MB]   
FROM sys.dm_db_xtp_checkpoint_files  
GROUP BY state, state_desc, file_type, file_type_desc  
ORDER BY state, file_type  
state_descstate_desc file_type_descfile_type_desc countcount on-disk size MBon-disk size MB
PRECREATEDPRECREATED DATADATA 1616 20482048
PRECREATEDPRECREATED DELTADELTA 1616 128128
UNDER CONSTRUCTIONUNDER CONSTRUCTION DATADATA 22 268268
UNDER CONSTRUCTIONUNDER CONSTRUCTION DELTADELTA 22 1616
ACTIVEACTIVE DATADATA 4141 56085608
ACTIVEACTIVE DELTADELTA 4141 328328

In questo caso, sono disponibili due coppie di file del checkpoint nello stato "in costruzione", il che significa che più coppie di file sono passate allo stato "in costruzione", probabilmente a causa dell'elevato livello di concorrenza del carico di lavoro.In this case, there are two checkpoint file pairs in the ‘under construction’ state, which means multiple file pairs were moved to the ‘under construction’ state, likely due to the high level of concurrency in the workload. Più thread simultanei hanno richiesto una nuova coppia di file contemporaneamente e di conseguenza una coppia è passata dallo stato di "precreato" a quello di "in costruzione".Multiple concurrent threads required a new file pair at the same time, and thus moved a pair from ‘precreated’ to ‘under construction’.

Vedere ancheSee Also

OLTP in memoria (ottimizzazione per la memoria)In-Memory OLTP (In-Memory Optimization)