
This guide will walk you through some of the performance features if you are running SQL Server on Linux . These are not unique or specific to Linux, but it helps to give you an idea of areas to investigate further.
Note
The following examples use the AdventureWorks sample database. For instructions on how to obtain and install this sample database, see
.Create a Columnstore Index
A columnstore index is a technology for storing and querying large stores of data in a columnar data format, called a columnstore.
Add a Columnstore index to the SalesOrderDetail table by executing the T-SQL below:
CREATE NONCLUSTERED COLUMNSTORE INDEX [IX_SalesOrderDetail_ColumnStore]
ON Sales.SalesOrderDetail
(UnitPrice, OrderQty, ProductID)
GO
Execute the following query that will use the Columnstore Index to scan the table:SELECT ProductID, SUM(UnitPrice) SumUnitPrice, AVG(UnitPrice) AvgUnitPrice,
SUM(OrderQty) SumOrderQty, AVG(OrderQty) AvgOrderQty
FROM Sales.SalesOrderDetail
GROUPBY ProductID
ORDERBY ProductID
Verify that the Columnstore Index was used by looking up the object_id for the Columnstore index and confirming that it appears in the usage stats for the SalesOrderDetail table:
SELECT * FROM sys.indexes WHEREname = 'IX_SalesOrderDetail_ColumnStore'
GO
SELECT *
FROM sys.dm_db_index_usage_stats
WHERE database_id = DB_ID('AdventureWorks')
AND object_id = OBJECT_ID('AdventureWorks.Sales.SalesOrderDetail');
Use In-Memory OLTP
SQL Server provides In-Memory OLTP features that can greatly improve the performance of application systems. This section of the Evaluation Guide will walk you through the steps to create a memory-optimized table stored in memory and a natively compiled stored procedure that can access the table without needing to be compiled or interpreted.
Configure Database for In-Memory OLTP
It’s recommended to set the database to a compatibility level of at least 130 to use In-Memory OLTP. Use the query below to check the current compatibility level of AdventureWorks:USE AdventureWorks
GO
SELECT d.compatibility_level
FROM sys.databases as d
WHERE d.name = Db_Name();
GO
If necessary, update the level to 130:
ALTERDATABASECURRENT
SET COMPATIBILITY_LEVEL = 130;
GO
When a transaction involves both a disk-based table and a memory-optimized table, it’s essential that the memory-optimized portion of the transaction operate at the transaction isolation level named SNAPSHOT. To reliably enforce this level for memory-optimized tables in a cross-container transaction, execute the following:
ALTERDATABASECURRENTSET MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT=ON
GO
Before you can create a memory-optimized table you must first create a Memory Optimized FILEGROUP and a container for data files:
ALTERDATABASE AdventureWorks ADD FILEGROUP AdventureWorks_mod CONTAINS memory_optimized_data
GO
ALTERDATABASE AdventureWorks ADDFILE (NAME='AdventureWorks_mod', FILENAME='c:\var\opt\mssql\data\AdventureWorks_mod') TO FILEGROUP AdventureWorks_mod
GO
Create a Memory-Optimized Table
The primary store for memory-optimized tables is main memory and so unlike disk-based tables, data does not need to be read in from disk into memory buffers. To create a memory-optimized table, use the MEMORY_OPTIMIZED = ON clause.
Execute the following query to create the memory-optimized table dbo.ShoppingCart. As a default, the data will be persisted on disk for durability purposes (Note that DURABILITY can also be set to persist the schema only).
CREATETABLE dbo.ShoppingCart (
ShoppingCartId INTIDENTITY(1,1) PRIMARY KEY NONCLUSTERED,
UserId INTNOTNULLINDEX ix_UserId NONCLUSTERED HASHWITH (BUCKET_COUNT=1000000),
CreatedDate DATETIME2 NOTNULL,
TotalPrice MONEY
) WITH (MEMORY_OPTIMIZED=ON)
GO
Insert some records into the table:
INSERT dbo.ShoppingCart VALUES (8798, SYSDATETIME(), NULL)
INSERT dbo.ShoppingCart VALUES (23, SYSDATETIME(), 45.4)
INSERT dbo.ShoppingCart VALUES (80, SYSDATETIME(), NULL)
INSERT dbo.ShoppingCart VALUES (342, SYSDATETIME(), 65.4)
Natively compiled Stored Procedure
SQL Server supports natively compiled stored procedures that access memory-optimized tables. The T-SQL statements are compiled to machine code and stored as native DLLs, enabling faster data access and more efficient query execution than traditional T-SQL. Stored procedures that are marked with NATIVE_COMPILATION are natively compiled.
CREATEPROCEDURE dbo.usp_InsertSampleCarts @InsertCount int
WITH NATIVE_COMPILATION, SCHEMABINDING AS
BEGIN ATOMIC
WITH (TRANSACTIONISOLATIONLEVEL = SNAPSHOT, LANGUAGE = N'us_english')
DECLARE @i int = 0
WHILE @i < @InsertCount
BEGIN
INSERTINTO dbo.ShoppingCart VALUES (1, SYSDATETIME() , NULL)
SET @i += 1
END
END
Insert 1,000,000 rows:
EXEC usp_InsertSampleCarts 1000000
Verify the rows have been inserted:
SELECTCOUNT(*) FROM dbo.ShoppingCart
Use Query Store
Query Store collects detailed performance information about queries, execution plans, and runtime statistics.
Query Store is not active by default and can be enabled with ALTER DATABASE:
ALTERDATABASE AdventureWorks SET QUERY_STORE = ON;
Run the following query to return information about queries and plans in the query store:
SELECT Txt.query_text_id, Txt.query_sql_text, Pl.plan_id, Qry.*
FROM sys.query_store_plan AS Pl
JOIN sys.query_store_query AS Qry
ON Pl.query_id = Qry.query_id
JOIN sys.query_store_query_text AS Txt
ON Qry.query_text_id = Txt.query_text_id ;
Query Dynamic Management Views
Dynamic management views return server state information that can be used to monitor the health of a server instance, diagnose problems, and tune performance.
To query the dm_os_wait stats dynamic management view:
SELECT wait_type, wait_time_ms
FROM sys.dm_os_wait_stats;