Ottimizzare le prestazioni tramite le tecnologie in memoria nel database SQLOptimize performance by using In-Memory technologies in SQL Database

Tramite le tecnologie in memoria del database SQL di Azure, è possibile migliorare le prestazioni di diversi carichi di lavoro: transazionale (elaborazione transazionale online o OLTP), analitica (elaborazione analitica online o OLAP) e mista (elaborazione ibrida transazione/analitica o HTAP).By using In-Memory technologies in Azure SQL Database, you can achieve performance improvements with various workloads: transactional (online transactional processing (OLTP)), analytics (online analytical processing (OLAP)), and mixed (hybrid transaction/analytical processing (HTAP)). Grazie a una più efficiente elaborazione delle query e delle transazioni, le tecnologie in memoria aiutano a ridurre i costi.Because of the more efficient query and transaction processing, In-Memory technologies also help you to reduce cost. In genere non è necessario aggiornare il piano tariffario del database per migliorare le prestazioni.You typically don't need to upgrade the pricing tier of the database to achieve performance gains. In alcuni casi infatti le tecnologie in memoria consentono di ridurre il piano tariffario e di osservare al contempo miglioramenti delle prestazioni.In some cases, you might even be able reduce the pricing tier, while still seeing performance improvements with In-Memory technologies.

Di seguito sono riportati due esempi che mostrano come la tecnologia OLTP in memoria abbia contribuito a migliorare significativamente le prestazioni.Here are two examples of how In-Memory OLTP helped to significantly improve performance:

Le tecnologie in memoria sono disponibili in tutti i database nel livello Premium, inclusi i database nei pool elastici Premium.In-Memory technologies are available in all databases in the Premium tier, including databases in Premium elastic pools.

Il video seguente spiega il potenziale miglioramento delle prestazioni con le tecnologie in memoria nel database SQL di Azure.The following video explains potential performance gains with In-Memory technologies in Azure SQL Database. Tenere presente che il miglioramento delle prestazioni dipende sempre da numerosi fattori, tra cui la natura del carico di lavoro e dei dati, il modello di accesso del database e così via.Remember that the performance gain that you see always depends on many factors, including the nature of the workload and data, access pattern of the database, and so on.

Il database SQL di Azure dispone delle seguenti tecnologie in memoria:Azure SQL Database has the following In-Memory technologies:

  • OLTP in memoria: aumenta la velocità effettiva e riduce la latenza per l'elaborazione delle transazioni.In-Memory OLTP increases throughput and reduces latency for transaction processing. Gli scenari che beneficiano dell'OLTP in memoria sono: elaborazione transazionale ad alta velocità di elaborazione, come l'inserimento di dati commerciali e da videogiochi, da eventi o dispositivi IoT, il caching, il caricamento di dati, le tabelle temporanee e gli scenari con variabili di tabella.Scenarios that benefit from In-Memory OLTP are: high-throughput transaction processing such as trading and gaming, data ingestion from events or IoT devices, caching, data load, and temporary table and table variable scenarios.
  • Gli indici columnstore cluster riducono fino a 10 volte il footprint della memoria e migliorano le prestazioni delle query di reporting e analisi.Clustered columnstore indexes reduce your storage footprint (up to 10 times) and improve performance for reporting and analytics queries. È possibile usare gli indici con tabelle dei fatti nei data mart per inserire più dati nel database e migliorare le prestazioni.You can use it with fact tables in your data marts to fit more data in your database and improve performance. Gli indici possono anche essere usati con i dati cronologici nel database operativo per archiviare ed essere in grado di eseguire una query su una quantità di dati 10 volte superiore.Also, you can use it with historical data in your operational database to archive and be able to query up to 10 times more data.
  • Gli indici columnstore non cluster per HTAP consentono di ottenere in tempo reale informazioni approfondite sull'azienda eseguendo una query direttamente sul database operativo, senza la necessità di eseguire un processo ETL dispendioso e attendere che il data warehouse venga popolato.Nonclustered columnstore indexes for HTAP help you to gain real-time insights into your business through querying the operational database directly, without the need to run an expensive extract, transform, and load (ETL) process and wait for the data warehouse to be populated. Gli indici columnstore non cluster consentono l'esecuzione molto rapida delle query di analisi nei database OLTP, riducendo l'impatto sul carico di lavoro operativo.Nonclustered columnstore indexes allow very fast execution of analytics queries on the OLTP database, while reducing the impact on the operational workload.
  • È possibile anche disporre di una tabella ottimizzata per la memoria con un indice columnstore.You can also have the combination of a memory-optimized table with a columnstore index. Tale combinazione consente di elaborare le transazioni e al contempo di eseguire le query di analisi sugli stessi dati in tempi estremamente rapidi.This combination enables you to perform very fast transaction processing, and to concurrently run analytics queries very quickly on the same data.

Gli indici columnstore e OLTP in memoria fanno parte di SQL Server rispettivamente dal 2012 e dal 2014.Both columnstore indexes and In-Memory OLTP have been part of the SQL Server product since 2012 and 2014, respectively. Il database SQL di Azure e SQL Server condividono la stessa implementazione delle tecnologie in memoria.Azure SQL Database and SQL Server share the same implementation of In-Memory technologies. In futuro, le nuove funzionalità per queste tecnologie verranno integrate prima nel database SQL di Azure e poi in SQL Server.Going forward, new capabilities for these technologies are released in Azure SQL Database first, before they are released in SQL Server.

Questo argomento descrive gli aspetti di OLTP in memoria e degli indici columnstore specifici del database SQL di Azure e include alcuni esempi:This topic describes aspects of In-Memory OLTP and columnstore indexes that are specific to Azure SQL Database and also includes samples:

  • Viene analizzato l'impatto di queste tecnologie sulla memoria e i limiti sulle dimensioni dei dati.You'll see the impact of these technologies on storage and data size limits.
  • Verrà illustrato come gestire lo spostamento dei database che sfruttano queste tecnologie tra i diversi piani tariffari.You'll see how to manage the movement of databases that use these technologies between the different pricing tiers.
  • Verranno esaminati due esempi che illustrano l'uso di OLTP in memoria e degli indici columnstore nel database SQL di Azure.You'll see two samples that illustrate the use of In-Memory OLTP, as well as columnstore indexes in Azure SQL Database.

Per altre informazioni, vedere le risorse seguenti.See the following resources for more information.

Approfondimento sulle tecnologie:In-depth information about the technologies:

Nozioni di base sull'OLTP in memoria: Avvio rapido 1: Tecnologie OLTP in memoria per ottimizzare le prestazioni di T-SQL, un altro articolo introduttivoA quick primer on In-Memory OLTP: Quick Start 1: In-Memory OLTP Technologies for Faster T-SQL Performance (another article to help you get started)

Video di approfondimento sulle tecnologie:In-depth videos about the technologies:

Dimensioni di archiviazione e datiStorage and data size

Limite su dimensioni dei dati e archiviazione per OLTP in memoriaData size and storage cap for In-Memory OLTP

OLTP in memoria include tabelle con ottimizzazione per la memoria, che vengono usate per archiviare i dati utente.In-Memory OLTP includes memory-optimized tables, which are used for storing user data. Queste tabelle devono rientrare nella memoria.These tables are required to fit in memory. Poiché la memoria è gestita direttamente nel servizio del database SQL, esiste il concetto di quota per i dati utente.Because you manage memory directly in the SQL Database service, we have the concept of a quota for user data. Questo concetto è definito archiviazione di OLTP in memoria.This idea is referred to as In-Memory OLTP storage.

Ogni piano tariffario relativo a database autonomi e pool elastici supportati include una certa quantità di spazio di archiviazione OLTP in memoria.Each supported standalone database pricing tier and each elastic pool pricing tier includes a certain amount of In-Memory OLTP storage. Al momento della redazione di questo articolo, è disponibile un gigabyte di spazio di archiviazione per ogni 125 unità di transazione di database (DTU) o unità di transazione di database elastico (eDTU).At the time of writing, you get a gigabyte of storage for every 125 database transaction units (DTUs) or elastic database transaction units (eDTUs).

L'articolo sui Livelli di servizio del database SQL contiene l'elenco ufficiale dello spazio di archiviazione OLTP in memoria disponibile per ogni piano tariffario di database autonomi e pool elastici supportati.The SQL Database service tiers article has the official list of the In-Memory OLTP storage that is available for each supported standalone database and elastic pool pricing tier.

Gli elementi seguenti rientrano nel limite di archiviazione di OLTP in memoria:The following items count toward your In-Memory OLTP storage cap:

  • Righe di dati utente attive nelle tabelle con ottimizzazione per la memoria e variabili di tabella.Active user data rows in memory-optimized tables and table variables. Si noti che le versioni precedenti della riga non vengono conteggiate nel limite.Note that old row versions don't count toward the cap.
  • Indici nelle tabelle con ottimizzazione per la memoria.Indexes on memory-optimized tables.
  • Costi operativi delle operazioni ALTER TABLE.Operational overhead of ALTER TABLE operations.

Se si raggiunge il limite, si riceve un errore di superamento della quota e non sarà più possibile inserire o aggiornare dati.If you hit the cap, you receive an out-of-quota error, and you are no longer able to insert or update data. Per risolvere il problema, eliminare i dati o aumentare il piano tariffario del database o del pool.To mitigate this error, delete data or increase the pricing tier of the database or pool.

Per dettagli sul monitoraggio dell'uso dello spazio di archiviazione OLTP in memoria e sulla configurazione degli avvisi al raggiungimento del limite, vedere Monitorare l'archiviazione in memoria.For details about monitoring In-Memory OLTP storage utilization and configuring alerts when you almost hit the cap, see Monitor In-Memory storage.

Informazioni sui pool elasticiAbout elastic pools

Con i pool elastici, lo spazio di archiviazione OLTP in memoria è condiviso tra tutti i database nel pool.With elastic pools, the In-Memory OLTP storage is shared across all databases in the pool. Ne consegue che l'utilizzo in un database può potenzialmente influire sugli altri database.Therefore, the usage in one database can potentially affect other databases. Esistono due metodi per la risoluzione di questo problema:Two mitigations for this are:

  • Configurare Max-eDTU per i database con numero di eDTU inferiore rispetto al numero di eDTU per l'intero pool.Configure a Max-eDTU for databases that is lower than the eDTU count for the pool as a whole. Ciò limita l'uso dello spazio di archiviazione OLTP in memoria in qualsiasi database del pool alla dimensione corrispondente al numero di eDTU.This maximum caps the In-Memory OLTP storage utilization, in any database in the pool, to the size that corresponds to the eDTU count.
  • Configurare Min-eDTU su un valore maggiore di 0.Configure a Min-eDTU that is greater than 0. In questo modo si garantisce che ogni database nel pool abbia a disposizione la quantità di spazio di archiviazione OLTP in memoria corrispondente al valore Min-eDTU configurato.This minimum guarantees that each database in the pool has the amount of available In-Memory OLTP storage that corresponds to the configured Min-eDTU.

Dimensioni dei dati e archiviazione per gli indici columnstoreData size and storage for columnstore indexes

Gli indici columnstore non devono essere contenuti nella memoria.Columnstore indexes aren't required to fit in memory. L'unico limite alla dimensione degli indici è quindi la dimensione complessiva massima del database, descritta nell'articolo Livelli di servizio del database SQL.Therefore, the only cap on the size of the indexes is the maximum overall database size, which is documented in the SQL Database service tiers article.

Quando si usano gli indici columnstore cluster, viene impiegata la compressione a colonne per l'archiviazione delle tabelle di base.When you use clustered columnstore indexes, columnar compression is used for the base table storage. Ciò può ridurre notevolmente il footprint di archiviazione dei dati utente, ovvero è possibile inserire più dati nel database.This compression can significantly reduce the storage footprint of your user data, which means that you can fit more data in the database. Usando la compressione a colonne dell'archivio, è possibile inserire una quantità ancora maggiore di dati.And the compression can be further increased with columnar archival compression. La quantità di compressione che è possibile ottenere dipende dalla natura dei dati, ma generalmente si aggira intorno a 10 volte (10X) la compressione tradizionale.The amount of compression that you can achieve depends on the nature of the data, but 10 times the compression is not uncommon.

Ad esempio, se si dispone di un database con dimensioni massime di 1 terabyte (TB) e si raggiunge una compressione 10X tramite columnstore, nel database è possibile inserire un totale di 10 TB di dati utente.For example, if you have a database with a maximum size of 1 terabyte (TB) and you achieve 10 times the compression by using columnstore indexes, you can fit a total of 10 TB of user data in the database.

Quando si usano indici columnstore non cluster, la tabella di base è ancora archiviata nel formato rowstore tradizionale.When you use nonclustered columnstore indexes, the base table is still stored in the traditional rowstore format. Pertanto, il risparmio di archiviazione non è paragonabile a quello ottenuto con gli indici columnstore cluster.Therefore, the storage savings aren't as big as with clustered columnstore indexes. Tuttavia, se si sostituisce un numero di indici non in cluster tradizionali con un indice columnstore singolo, è sempre possibile riscontrare un risparmio complessivo nel footprint della memoria per la tabella.However, if you're replacing a number of traditional nonclustered indexes with a single columnstore index, you can still see an overall savings in the storage footprint for the table.

Spostamento dei database tra i piani tariffari tramite tecnologie in memoriaMoving databases that use In-Memory technologies between pricing tiers

Passando a un piano tariffario superiore, ad esempio da Standard a Premium, non si corre mai il rischio di incompatibilità o altri problemi.There are never any incompatibilities or other problems when you upgrade to a higher pricing tier, such as from Standard to Premium. Il passaggio implica semplicemente un aumento di funzionalità e risorse.The available functionality and resources only increase.

Tuttavia, eseguire il downgrade del piano tariffario può avere un impatto negativo sul database.But downgrading the pricing tier can negatively impact your database. Questo impatto è particolarmente evidente quando si effettua il downgrade da Premium a Standard o Basic nei casi in cui il database contenga oggetti di OLTP In memoria.The impact is especially apparent when you downgrade from Premium to Standard or Basic when your database contains In-Memory OLTP objects. Le tabelle ottimizzate per la memoria e gli indici columnstore non sono disponibili dopo il downgrade, anche se dovessero rimanere visibili.Memory-optimized tables, and columnstore indexes, are unavailable after the downgrade (even if they remain visible). Le stesse considerazioni si applicano quando si effettua il downgrade del piano tariffario di un pool elastico o quando si esegue lo spostamento dei database con tecnologie in memoria in un pool elastico Standard o Basic.The same considerations apply when you're lowering the pricing tier of an elastic pool, or moving a database with In-Memory technologies, into a Standard or Basic elastic pool.

OLTP in memoriaIn-Memory OLTP

Downgrade a Basic/Standard: OLTP in memoria non è supportato nei database del piano Standard o Basic.Downgrading to Basic/Standard: In-Memory OLTP isn't supported in databases in the Standard or Basic tier. Non è possibile spostare un database che contiene oggetti OLTP in memoria al piano tariffario Standard o Basic.In addition, it isn't possible to move a database that has any In-Memory OLTP objects to the Standard or Basic tier.

Esiste un modo a livello di codice per capire se un determinato database supporta OLTP in memoria.There is a programmatic way to understand whether a given database supports In-Memory OLTP. È possibile eseguire la query Transact-SQL seguente:You can execute the following Transact-SQL query:

SELECT DatabasePropertyEx(DB_NAME(), 'IsXTPSupported');

Se la query restituisce 1, OLTP in memoria è supportato nel database.If the query returns 1, In-Memory OLTP is supported in this database.

Prima di eseguire il downgrade del database al livello Standard o Basic, rimuovere tutti i tipi di tabella e le tabelle con ottimizzazione per la memoria, nonché tutti i moduli T-SQL compilati in modo nativo.Before you downgrade the database to Standard/Basic, remove all memory-optimized tables and table types, as well as all natively compiled T-SQL modules. Le query seguenti identificano tutti gli oggetti che devono essere rimossi prima eseguire il downgrade di un database al piano Standard o Basic:The following queries identify all objects that need to be removed before a database can be downgraded to Standard/Basic:

SELECT * FROM sys.tables WHERE is_memory_optimized=1
SELECT * FROM sys.table_types WHERE is_memory_optimized=1
SELECT * FROM sys.sql_modules WHERE uses_native_compilation=1

Downgrade a un livello Premium inferiore: i dati nelle tabelle con ottimizzazione per la memoria devono essere contenuti nell'archiviazione OLTP in memoria associata al piano tariffario del database o disponibile nel pool elastico.Downgrading to a lower Premium tier: Data in memory-optimized tables must fit within the In-Memory OLTP storage that is associated with the pricing tier of the database or is available in the elastic pool. Se si tenta di eseguire il downgrade del piano tariffario o di spostare il database in un pool che non dispone di sufficiente spazio di archiviazione OLTP in memoria, l'operazione avrà esito negativo.If you try to lower the pricing tier or move the database into a pool that doesn't have enough available In-Memory OLTP storage, the operation fails.

Indici ColumnstoreColumnstore indexes

Downgrade a Basic o Standard: gli indici columnstore sono supportati solo nel piano tariffario Premium e non nei livelli Standard o Basic.Downgrading to Basic or Standard: Columnstore indexes are supported only on the Premium pricing tier, and not on the Standard or Basic tiers. Quando si effettua il downgrade del database al piano Standard o Basic, l'indice columnstore non è più disponibile.When you downgrade your database to Standard or Basic, your columnstore index becomes unavailable. Il sistema conserva l'indice columnstore, ma non lo usa mai.The system maintains your columnstore index, but it never leverages the index. Se in seguito si torna al piano Premium, l'indice columnstore torna subito disponibile all'uso.If you later upgrade back to Premium, your columnstore index is immediately ready to be leveraged again.

Se dispone di un indice columnstore cluster, l'intera tabella non sarà più disponibile dopo il downgrade del livello.If you have a clustered columnstore index, the whole table becomes unavailable after tier downgrade. Pertanto è consigliabile eliminare tutti gli indici columnstore cluster prima di effettuare il downgrade del database al di sotto del livello Premium.Therefore we recommend that you drop all clustered columnstore indexes before you downgrade your database below the Premium tier.

Downgrade a un livello Premium inferiore: il downgrade avrà esito positivo se l'intero database rientra nelle dimensioni massime dei database relative al piano tariffario di destinazione o all'archiviazione disponibile nel pool elastico.Downgrading to a lower Premium tier: This downgrade succeeds if the whole database fits within the maximum database size for the target pricing tier, or within the available storage in the elastic pool. Non è previsto alcun impatto specifico dagli indici columnstore.There is no specific impact from the columnstore indexes.

 

1. Installare l'esempio di OLTP in memoria1. Install the In-Memory OLTP sample

È possibile creare il database AdventureWorksLT di esempio con pochi clic nel portale di Azure.You can create the AdventureWorksLT sample database with a few clicks in the Azure portal. I passaggi descritti in questa sezione illustrano come migliorare il database AdventureWorksLT con oggetti OLTP in memoria e dimostra i vantaggi sulle prestazioni.Then, the steps in this section explain how you can enrich your AdventureWorksLT database with In-Memory OLTP objects and demonstrate performance benefits.

Per una dimostrazione più semplice e visivamente più interessante sulle prestazioni di OLTP in memoria, vedere:For a more simplistic, but more visually appealing performance demo for In-Memory OLTP, see:

Procedura di installazioneInstallation steps

  1. Nel portale di Azurecreare un database Premium in un server.In the Azure portal, create a Premium database on a server. Impostare Origine sul database AdventureWorksLT di esempio.Set the Source to the AdventureWorksLT sample database. Per istruzioni dettagliate, vedere Creare il primo database SQL di Azure.For detailed instructions, see Create your first Azure SQL database.

  2. Connettersi al database con SQL Server Management Studio (SSMS.exe).Connect to the database with SQL Server Management Studio (SSMS.exe).

  3. Copiare lo script Transact-SQL OLTP in memoria negli Appunti.Copy the In-Memory OLTP Transact-SQL script to your clipboard. Lo script T-SQL crea gli oggetti in memoria necessari nel database AdventureWorksLT di esempio creato nel passaggio 1.The T-SQL script creates the necessary In-Memory objects in the AdventureWorksLT sample database that you created in step 1.

  4. Incollare lo script T-SQL in SSMS.exe, quindi eseguirlo.Paste the T-SQL script into SSMS, and then execute the script. La clausola MEMORY_OPTIMIZED = ON è fondamentale nelle istruzioni CREATE TABLE,The MEMORY_OPTIMIZED = ON clause CREATE TABLE statements are crucial. ad esempio:For example:

CREATE TABLE [SalesLT].[SalesOrderHeader_inmem](
    [SalesOrderID] int IDENTITY NOT NULL PRIMARY KEY NONCLUSTERED ...,
    ...
) WITH (MEMORY_OPTIMIZED = ON);

Errore 40536Error 40536

Se viene visualizzato l'errore 40536 quando si esegue lo script T-SQL, verificare se il database supporta le funzionalità in memoria eseguendo questo script T-SQL:If you get error 40536 when you run the T-SQL script, run the following T-SQL script to verify whether the database supports In-Memory:

SELECT DatabasePropertyEx(DB_Name(), 'IsXTPSupported');

Se il risultato è 0, le funzionalità in memoria non sono supportate, mentre 1 indica che sono supportate.A result of 0 means that In-Memory isn't supported, and 1 means that it is supported. Per diagnosticare il problema, verificare che il livello di servizio del database sia Premium.To diagnose the problem, ensure that the database is at the Premium service tier.

Informazioni sugli elementi creati con ottimizzazione per la memoriaAbout the created memory-optimized items

Tabelle: l'esempio contiene le tabelle con ottimizzazione per la memoria seguenti.Tables: The sample contains the following memory-optimized tables:

  • SalesLT.Product_inmemSalesLT.Product_inmem
  • SalesLT.SalesOrderHeader_inmemSalesLT.SalesOrderHeader_inmem
  • SalesLT.SalesOrderDetail_inmemSalesLT.SalesOrderDetail_inmem
  • Demo.DemoSalesOrderHeaderSeedDemo.DemoSalesOrderHeaderSeed
  • Demo.DemoSalesOrderDetailSeedDemo.DemoSalesOrderDetailSeed

È possibile esaminare le tabelle con ottimizzazione per la memoria tramite Esplora oggetti in SSMS.You can inspect memory-optimized tables through the Object Explorer in SSMS. Fare doppio clic su Tabelle > Filtro > Impostazioni filtro > Con ottimizzazione per la memoria.Right-click Tables > Filter > Filter Settings > Is Memory Optimized. Il valore è uguale a 1.The value equals 1.

In alternativa, è possibile eseguire una query delle viste del catalogo, ad esempio:Or you can query the catalog views, such as:

SELECT is_memory_optimized, name, type_desc, durability_desc
    FROM sys.tables
    WHERE is_memory_optimized = 1;

Stored procedure compilata in modo nativo: è possibile esaminare SalesLT.usp_InsertSalesOrder_inmem usando una query delle viste del catalogo.Natively compiled stored procedure: You can inspect SalesLT.usp_InsertSalesOrder_inmem through a catalog view query:

SELECT uses_native_compilation, OBJECT_NAME(object_id), definition
    FROM sys.sql_modules
    WHERE uses_native_compilation = 1;

 

Eseguire il carico di lavoro OLTP di esempioRun the sample OLTP workload

L'unica differenza tra le due stored procedure seguenti è che la prima usa versioni con ottimizzazione per la memoria delle tabelle, mentre la seconda usa tabelle basate su disco tradizionali:The only difference between the following two stored procedures is that the first procedure uses memory-optimized versions of the tables, while the second procedure uses the regular on-disk tables:

  • SalesLT.usp_InsertSalesOrder_inmemSalesLT.usp_InsertSalesOrder_inmem
  • SalesLT.usp_InsertSalesOrder_ondiskSalesLT.usp_InsertSalesOrder_ondisk

Questa sezione illustra come usare l'utilità ostress.exe per eseguire le due stored procedure in condizioni di sovraccarico.In this section, you see how to use the handy ostress.exe utility to execute the two stored procedures at stressful levels. È possibile mettere a confronto i tempi necessari per il completamento dei due test di stress.You can compare how long it takes for the two stress runs to finish.

Quando si esegue ostress.exe, è consigliabile passare valori di parametri specifici a entrambe:When you run ostress.exe, we recommend that you pass parameter values designed for both of the following:

  • Eseguire un numero elevato di connessioni simultanee, usando -n100.Run a large number of concurrent connections, by using -n100.
  • Ripetere ogni ciclo di connessione centinaia di volte, usando -r500.Have each connection loop hundreds of times, by using -r500.

È opportuno, tuttavia, iniziare con valori molto più bassi, ad esempio -n10 e -r50, per assicurarsi che tutto funzioni correttamente.However, you might want to start with much smaller values like -n10 and -r50 to ensure that everything is working.

Script per ostress.exeScript for ostress.exe

Questa sezione illustra lo script T-SQL incorporato nella riga di comando ostress.exe.This section displays the T-SQL script that is embedded in our ostress.exe command line. Lo script usa gli elementi creati dallo script T-SQL installato in precedenza.The script uses items that were created by the T-SQL script that you installed earlier.

Lo script riportato di seguito inserisce un ordine di vendita di esempio con cinque voci nelle tabellecon ottimizzazione per la memoria seguenti:The following script inserts a sample sales order with five line items into the following memory-optimized tables:

  • SalesLT.SalesOrderHeader_inmemSalesLT.SalesOrderHeader_inmem
  • SalesLT.SalesOrderDetail_inmemSalesLT.SalesOrderDetail_inmem
DECLARE
    @i int = 0,
    @od SalesLT.SalesOrderDetailType_inmem,
    @SalesOrderID int,
    @DueDate datetime2 = sysdatetime(),
    @CustomerID int = rand() * 8000,
    @BillToAddressID int = rand() * 10000,
    @ShipToAddressID int = rand() * 10000;

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

WHILE (@i < 20)
begin;
    EXECUTE SalesLT.usp_InsertSalesOrder_inmem @SalesOrderID OUTPUT,
        @DueDate, @CustomerID, @BillToAddressID, @ShipToAddressID, @od;
    SET @i = @i + 1;
end

Per creare la versione _ondisk dello script T-SQL precedente per ostress.exe, occorre sostituire le due occorrenze della sottostringa _inmem con _ondisk.To make the _ondisk version of the preceding T-SQL script for ostress.exe, you would replace both occurrences of the _inmem substring with _ondisk. Queste sostituzioni interessano i nomi delle tabelle e delle stored procedure.These replacements affect the names of tables and stored procedures.

Installare le utilità RML e ostressInstall RML utilities and ostress

È consigliabile pianificare l'esecuzione di ostress.exe su una macchina virtuale di Azure.Ideally, you would plan to run ostress.exe on an Azure virtual machine (VM). Creare una macchina virtuale di Azure nella stessa area geografica di Azure in cui risiede il database AdventureWorksLT.You would create an Azure VM in the same Azure geographic region where your AdventureWorksLT database resides. È possibile eseguire ostress.exe sul computer portatile.But you can run ostress.exe on your laptop instead.

Installare nella macchina virtuale o nell'host scelto le utilità RML (Replay Markup Language),On the VM, or on whatever host you choose, install the Replay Markup Language (RML) utilities. che includono ostress.exe.The utilities include ostress.exe.

Per altre informazioni, vedere:For more information, see:

Eseguire prima di tutto il test di stress del carico di lavoro per _inmemRun the _inmem stress workload first

Per eseguire la riga di comando ostress.exe è possibile usare una finestra del prompt dei comandi RML .You can use an RML Cmd Prompt window to run our ostress.exe command line. I parametri della riga di comando indicano al comando ostress di:The command-line parameters direct ostress to:

  • Eseguire 100 connessioni simultaneamente (-n100).Run 100 connections concurrently (-n100).
  • Fare in modo che ogni connessione esegua lo script T-SQL 50 volte (-r50).Have each connection run the T-SQL script 50 times (-r50).
ostress.exe -n100 -r50 -S<servername>.database.windows.net -U<login> -P<password> -d<database> -q -Q"DECLARE @i int = 0, @od SalesLT.SalesOrderDetailType_inmem, @SalesOrderID int, @DueDate datetime2 = sysdatetime(), @CustomerID int = rand() * 8000, @BillToAddressID int = rand() * 10000, @ShipToAddressID int = rand()* 10000; INSERT INTO @od SELECT OrderQty, ProductID FROM Demo.DemoSalesOrderDetailSeed WHERE OrderID= cast((rand()*60) as int); WHILE (@i < 20) begin; EXECUTE SalesLT.usp_InsertSalesOrder_inmem @SalesOrderID OUTPUT, @DueDate, @CustomerID, @BillToAddressID, @ShipToAddressID, @od; set @i += 1; end"

Per eseguire la riga di comando ostress.exe precedente:To run the preceding ostress.exe command line:

  1. Reimpostare il contenuto dei dati del database eseguendo questo comando in SSMS per eliminare tutti i dati inseriti da esecuzioni precedenti: Reset the database data content by running the following command in SSMS, to delete all the data that was inserted by any previous runs:

    EXECUTE Demo.usp_DemoReset;
    
  2. Copiare il testo della riga di comando ostress.exe precedente negli Appunti.Copy the text of the preceding ostress.exe command line to your clipboard.

  3. Sostituire <placeholders> per i parametri -S -U -P -d con i valori reali corretti.Replace the <placeholders> for the parameters -S -U -P -d with the correct real values.

  4. Eseguire la riga di comando modificata in una finestra dei comandi RML.Run your edited command line in an RML Cmd window.

Il risultato è un intervallo di tempoResult is a duration

Al termine, ostress.exe scrive la durata dell'esecuzione come ultima riga di output nella finestra dei comandi RML.When ostress.exe finishes, it writes the run duration as its final line of output in the RML Cmd window. Ad esempio, per un'esecuzione dei test più breve, durata circa 1,5 minuti:For example, a shorter test run lasted about 1.5 minutes:

11/12/15 00:35:00.873 [0x000030A8] OSTRESS exiting normally, elapsed time: 00:01:31.867

Reimpostare, modificare per l'esecuzione _ondisk ed eseguire di nuovo il testReset, edit for _ondisk, then rerun

Dopo aver ottenuto il risultato dell'esecuzione _inmem, seguire la procedura indicata di seguito per l'esecuzione _ondisk:After you have the result from the _inmem run, perform the following steps for the _ondisk run:

  1. Reimpostare il database eseguendo questo comando in SSMS per eliminare tutti i dati inseriti dall'esecuzione precedente:Reset the database by running the following command in SSMS to delete all the data that was inserted by the previous run:

    EXECUTE Demo.usp_DemoReset;
    
  2. Modificare la riga di comando ostress.exe per sostituire tutte le occorrenze di _inmem con _ondisk.Edit the ostress.exe command line to replace all _inmem with _ondisk.

  3. Eseguire ostress.exe per la seconda volta e acquisire il risultato relativo alla durata.Rerun ostress.exe for the second time, and capture the duration result.

  4. Reimpostare nuovamente il database, per eliminare in modo responsabile una potenziale grande quantità di dati di test.Again, reset the database (for responsibly deleting what can be a large amount of test data).

Risultati previsti per il confrontoExpected comparison results

I test delle funzionalità in memoria hanno mostrato un miglioramento delle prestazioni pari a 9 volte per questo semplice carico di lavoro, con l'utilità ostress in esecuzione in una VM di Azure nella stessa area di Azure del database.Our In-Memory tests have shown that performance improved by nine times for this simplistic workload, with ostress running on an Azure VM in the same Azure region as the database.

 

2. Installare l'esempio di analisi in memoria2. Install the In-Memory Analytics sample

In questa sezione vengono messi a confronto i risultati di statistiche e IO quando si usa un indice columnstore rispetto a un indice ad albero B tradizionale.In this section, you compare the IO and statistics results when you're using a columnstore index versus a traditional b-tree index.

Per l'analisi in tempo reale in un carico di lavoro OLTP, è spesso preferibile usare un indice columnstore non cluster.For real-time analytics on an OLTP workload, it's often best to use a nonclustered columnstore index. Per informazioni dettagliate, vedere Descrizione degli indici columnstore.For details, see Columnstore Indexes Described.

Preparare il test di analisi columnstorePrepare the columnstore analytics test

  1. Usare il portale di Azure per creare un nuovo database AdventureWorksLT dall'esempio.Use the Azure portal to create a fresh AdventureWorksLT database from the sample.

    • Usare esattamente questo nome.Use that exact name.
    • Scegliere qualsiasi livello di servizio Premium.Choose any Premium service tier.
  2. Copiare sql_in-memory_analytics_sample negli Appunti.Copy the sql_in-memory_analytics_sample to your clipboard.

    • Lo script T-SQL crea gli oggetti in memoria necessari nel database AdventureWorksLT di esempio creato nel passaggio 1.The T-SQL script creates the necessary In-Memory objects in the AdventureWorksLT sample database that you created in step 1.
    • Lo script crea la tabella delle dimensioni e due tabelle dei fatti.The script creates the Dimension table and two fact tables. Ogni tabella dei fatti viene popolata con 3,5 milioni di righe.The fact tables are populated with 3.5 million rows each.
    • Il completamento dello script potrebbe richiedere 15 minuti.The script might take 15 minutes to complete.
  3. Incollare lo script T-SQL in SSMS.exe, quindi eseguirlo.Paste the T-SQL script into SSMS, and then execute the script. La parola chiave COLUMNSTORE è fondamentale in una istruzione CREATE INDEX, ad esempio:The COLUMNSTORE keyword in the CREATE INDEX statement is crucial, as in:
    CREATE NONCLUSTERED COLUMNSTORE INDEX ...;

  4. Impostare AdventureWorksLT sul livello di compatibilità 130:Set AdventureWorksLT to compatibility level 130:
    ALTER DATABASE AdventureworksLT SET compatibility_level = 130;

    Il livello 130 non è direttamente correlato alle funzionalità in memoria,Level 130 is not directly related to In-Memory features. ma offre in genere prestazioni delle query più veloci rispetto al livello 120.But level 130 generally provides faster query performance than 120.

Tabelle e indici columnstore fondamentaliKey tables and columnstore indexes

  • dbo.FactResellerSalesXL_CCI è una tabella contenente un indice columnstore cluster, che presenta una compressione avanzata a livello di dati.dbo.FactResellerSalesXL_CCI is a table that has a clustered columnstore index, which has advanced compression at the data level.

  • dbo.FactResellerSalesXL_PageCompressed è una tabella contenente un indice cluster equivalente tradizionale, che presenta una compressione solo a livello di pagina.dbo.FactResellerSalesXL_PageCompressed is a table that has an equivalent regular clustered index, which is compressed only at the page level.

Query fondamentali per il confronto dell'indice columnstoreKey queries to compare the columnstore index

Sono disponibili diversi tipi di query T-SQ che è possibile eseguire per migliorare le prestazioni.There are several T-SQL query types that you can run to see performance improvements. Nel passaggio 2 nello script T-SQL, prestare attenzione a questa coppia di query.In step 2 in the T-SQL script, pay attention to this pair of queries. Le due query differiscono per una sola riga:They differ only on one line:

  • FROM FactResellerSalesXL_PageCompressed a
  • FROM FactResellerSalesXL_CCI a

Un indice columnstore cluster si trova nella tabella FactResellerSalesXL_CCI.A clustered columnstore index is in the FactResellerSalesXL_CCI table.

L'estratto dallo script T-SQL riportato di seguito permette di stampare le statistiche per IO e TIME per la query di ogni tabella.The following T-SQL script excerpt prints statistics for IO and TIME for the query of each table.

/*********************************************************************
Step 2 -- Overview
-- Page Compressed BTree table v/s Columnstore table performance differences
-- Enable actual Query Plan in order to see Plan differences when Executing
*/
-- Ensure Database is in 130 compatibility mode
ALTER DATABASE AdventureworksLT SET compatibility_level = 130
GO

-- Execute a typical query that joins the Fact Table with dimension tables
-- Note this query will run on the Page Compressed table, Note down the time
SET STATISTICS IO ON
SET STATISTICS TIME ON
GO

SELECT c.Year
    ,e.ProductCategoryKey
    ,FirstName + ' ' + LastName AS FullName
    ,count(SalesOrderNumber) AS NumSales
    ,sum(SalesAmount) AS TotalSalesAmt
    ,Avg(SalesAmount) AS AvgSalesAmt
    ,count(DISTINCT SalesOrderNumber) AS NumOrders
    ,count(DISTINCT a.CustomerKey) AS CountCustomers
FROM FactResellerSalesXL_PageCompressed a
INNER JOIN DimProduct b ON b.ProductKey = a.ProductKey
INNER JOIN DimCustomer d ON d.CustomerKey = a.CustomerKey
Inner JOIN DimProductSubCategory e on e.ProductSubcategoryKey = b.ProductSubcategoryKey
INNER JOIN DimDate c ON c.DateKey = a.OrderDateKey
GROUP BY e.ProductCategoryKey,c.Year,d.CustomerKey,d.FirstName,d.LastName
GO
SET STATISTICS IO OFF
SET STATISTICS TIME OFF
GO


-- This is the same Prior query on a table with a clustered columnstore index CCI
-- The comparison numbers are even more dramatic the larger the table is (this is an 11 million row table only)
SET STATISTICS IO ON
SET STATISTICS TIME ON
GO
SELECT c.Year
    ,e.ProductCategoryKey
    ,FirstName + ' ' + LastName AS FullName
    ,count(SalesOrderNumber) AS NumSales
    ,sum(SalesAmount) AS TotalSalesAmt
    ,Avg(SalesAmount) AS AvgSalesAmt
    ,count(DISTINCT SalesOrderNumber) AS NumOrders
    ,count(DISTINCT a.CustomerKey) AS CountCustomers
FROM FactResellerSalesXL_CCI a
INNER JOIN DimProduct b ON b.ProductKey = a.ProductKey
INNER JOIN DimCustomer d ON d.CustomerKey = a.CustomerKey
Inner JOIN DimProductSubCategory e on e.ProductSubcategoryKey = b.ProductSubcategoryKey
INNER JOIN DimDate c ON c.DateKey = a.OrderDateKey
GROUP BY e.ProductCategoryKey,c.Year,d.CustomerKey,d.FirstName,d.LastName
GO

SET STATISTICS IO OFF
SET STATISTICS TIME OFF
GO

In un database con piano tariffario P2 è possibile raggiungere circa 9X il guadagno sulle prestazioni per la query tramite l'indice columnstore cluster rispetto a un indice tradizionale.In a database with the P2 pricing tier, you can expect about nine times the performance gain for this query by using the clustered columnstore index compared with the traditional index. Con P15, è possibile prevedere un miglioramento delle prestazioni pari a 57X usando l'indice columnstore.With P15, you can expect about 57 times the performance gain by using the columnstore index.

Passaggi successiviNext steps

Risorse aggiuntiveAdditional resources

ApprofondimentiDeeper information

Progettazione di applicazioniApplication design

StrumentiTools