You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[!INCLUDE [SQL Server Azure SQL Database PDW FabricSQLDB](../../includes/applies-to-version/sql-asdb-asdbmi-pdw-fabricsqldb.md)]
16
18
17
-
Columnstore indexes, in conjunction with partitioning, are essential for building a [!INCLUDE [ssNoVersion](../../includes/ssnoversion-md.md)] data warehouse. This article focuses on key use cases and examples for data warehousing designs with the SQL Database Engine.
18
-
19
+
Columnstore indexes, in conjunction with partitioning, are essential for building a [!INCLUDE [ssNoVersion](../../includes/ssnoversion-md.md)] data warehouse. This article focuses on key use cases and examples for data warehousing designs with the SQL Database Engine.
20
+
19
21
## Key features for data warehousing
20
22
21
-
[!INCLUDE [sssql16-md](../../includes/sssql16-md.md)] introduced these features for columnstore performance enhancements:
22
-
23
-
-Always On supports querying a columnstore index on a readable secondary replica.
24
-
-Multiple Active Result Sets (MARS) supports columnstore indexes.
25
-
-A new dynamic management view [sys.dm_db_column_store_row_group_physical_stats (Transact-SQL)](../system-dynamic-management-views/sys-dm-db-column-store-row-group-physical-stats-transact-sql.md) provides performance troubleshooting information at the row group level.
26
-
- Single-threaded queries on columnstore indexes can run in batch mode. Previously, only multi-threaded queries could run in batch mode.
27
-
-The `SORT` operator runs in batch mode.
28
-
-Multiple `DISTINCT` operations run in batch mode.
29
-
-Window Aggregates now runs in batch mode for database compatibility level 130 and higher.
30
-
-Aggregate Pushdown for efficient processing of aggregates. This is supported on all database compatibility levels.
31
-
-String predicate pushdown for efficient processing of string predicates. This is supported on all database compatibility levels.
32
-
-Snapshot isolation for database compatibility level 130 and higher.
33
-
-Ordered clustered columnstore indexes were introduced with [!INCLUDE [sql-server-2022](../../includes/sssql22-md.md)]. For more information, see [CREATE COLUMNSTORE INDEX](../../t-sql/statements/create-columnstore-index-transact-sql.md#order-for-clustered-columnstore) and [Performance tuning with ordered columnstore indexes](ordered-columnstore-indexes.md). For ordered columnstore index availability, see [Ordered column index availability](columnstore-indexes-overview.md#ordered-columnstore-index-availability).
23
+
[!INCLUDE [sssql16-md](../../includes/sssql16-md.md)] introduced these features for columnstore performance enhancements:
24
+
25
+
- Always On supports querying a columnstore index on a readable secondary replica.
26
+
- Multiple Active Result Sets (MARS) supports columnstore indexes.
27
+
- A new dynamic management view [sys.dm_db_column_store_row_group_physical_stats (Transact-SQL)](../system-dynamic-management-views/sys-dm-db-column-store-row-group-physical-stats-transact-sql.md) provides performance troubleshooting information at the row group level.
28
+
-Serial queries on columnstore indexes can run in batch mode. Previously, only parallel queries could run in batch mode.
29
+
- The *sort* operator runs in batch mode.
30
+
- Multiple *distinct* operations run in batch mode.
31
+
- Window aggregates now runs in batch mode for database compatibility level 130 and higher.
32
+
- Aggregate pushdown for efficient processing of aggregates. This is supported on all database compatibility levels.
33
+
- String predicate pushdown for efficient processing of string predicates. This is supported on all database compatibility levels.
34
+
- Snapshot isolation for database compatibility level 130 and higher.
35
+
- Ordered clustered columnstore indexes were introduced with [!INCLUDE [sql-server-2022](../../includes/sssql22-md.md)]. For more information, see [CREATE COLUMNSTORE INDEX](../../t-sql/statements/create-columnstore-index-transact-sql.md#order-for-clustered-columnstore) and [Performance tuning with ordered columnstore indexes](ordered-columnstore-indexes.md). For ordered columnstore index availability, see [Ordered column index availability](columnstore-indexes-overview.md#ordered-columnstore-index-availability).
34
36
35
37
For more information about new features in versions and platforms of SQL Server and Azure SQL, see [What's new in columnstore indexes](columnstore-indexes-what-s-new.md).
36
-
38
+
37
39
## Improve performance by combining nonclustered and columnstore indexes
38
-
Starting with [!INCLUDE [sssql16-md](../../includes/sssql16-md.md)], you can define rowstore nonclustered indexes on a clustered columnstore index.
39
-
40
+
41
+
Starting with [!INCLUDE [sssql16-md](../../includes/sssql16-md.md)], you can create rowstore nonclustered indexes on a clustered columnstore index.
42
+
40
43
### Example: Improve efficiency of table seeks with a nonclustered index
41
-
To improve efficiency of table seeks in a data warehouse, you can create a nonclustered index designed to run queries that perform best with table seeks. For example, queries that look for matching values or return a small range of values perform better against a B-tree index rather than a columnstore index. They don't require a full table scan through the columnstore index and return the correct result faster by doing a binary search through a B-tree index.
42
-
43
-
```sql
44
-
--BASIC EXAMPLE: Create a nonclustered index on a columnstore table.
45
-
46
-
--Create the table
47
-
CREATETABLEt_account (
48
-
AccountKey intNOT NULL,
49
-
AccountDescription nvarchar (50),
50
-
AccountType nvarchar(50),
51
-
UnitSold int
52
-
);
53
-
GO
54
-
44
+
45
+
To improve efficiency of table seeks in a data warehouse, you can create a nonclustered index designed to run queries that perform best with table seeks. For example, queries that look for matching values or return a small range of values perform better against a B-tree index rather than a columnstore index. They don't require a full scan of the columnstore index and return the correct result faster by doing a binary search through a B-tree index.
46
+
47
+
```sql
48
+
--BASIC EXAMPLE: Create a nonclustered index on a columnstore table.
49
+
50
+
--Create the table
51
+
CREATETABLEt_account (
52
+
AccountKey intNOT NULL,
53
+
AccountDescription nvarchar(50),
54
+
AccountType nvarchar(50),
55
+
UnitSold int
56
+
);
57
+
55
58
--Store the table as a columnstore.
56
-
CREATE CLUSTERED COLUMNSTORE INDEX taccount_cci ON t_account;
### Example: Use a nonclustered index to enforce a primary key constraint on a columnstore table
64
66
65
-
By design, a columnstore table doesn't allow a clustered primary key constraint. Now you can use a nonclustered index on a columnstore table to enforce a primary key constraint. A primary key is equivalent to a UNIQUE constraint on a non-NULL column, and [!INCLUDE [ssNoVersion](../../includes/ssnoversion-md.md)] implements a UNIQUE constraint as a nonclustered index. Combining these facts, the following example defines a UNIQUE constraint on the non-NULL column accountkey. The result is a nonclustered index that enforces a primary key constraint as a UNIQUE constraint on a non-NULL column.
66
-
67
-
Next, the table is converted to a clustered columnstore index. During the conversion, the nonclustered index persists. The result is a clustered columnstore index with a nonclustered index that enforces a primary key constraint. Since any update or insert on the columnstore table also affects the nonclustered index, all operations that violate the unique constraint and the non-NULL causes the entire operation to fail.
68
-
69
-
The result is a columnstore index with a nonclustered index that enforces a primary key constraint on both indexes.
70
-
67
+
By design, a columnstore table doesn't allow a clustered primary key constraint. Now you can use a nonclustered index on a columnstore table to enforce uniqueness. A primary key is equivalent to a `UNIQUE` constraint on a non-NULL column, and [!INCLUDE [ssNoVersion](../../includes/ssnoversion-md.md)] implements a `UNIQUE` constraint as a nonclustered index. Combining these facts, the following example defines a `UNIQUE` constraint on the non-NULL column `AccountKey`. The result is a nonclustered index that enforces uniquness on a non-NULL column.
68
+
69
+
Next, the table is converted to a clustered columnstore index. During the conversion, the nonclustered index persists. The result is a clustered columnstore index with a nonclustered index that enforces uniqueness. Since any update or insert on the columnstore table also affects the nonclustered index, all operations that violate the unique constraint and the non-NULL constraint cause the entire operation to fail.
70
+
71
+
The result is a columnstore index with a nonclustered index that enforces uniqueness on both indexes.
72
+
71
73
```sql
72
-
--EXAMPLE: Enforce a primary key constraint on a columnstore table.
73
-
74
-
--Create a rowstore table with a unique constraint.
75
-
--The unique constraint is implemented as a nonclustered index.
76
-
CREATETABLEt_account (
77
-
AccountKey intNOT NULL,
78
-
AccountDescription nvarchar (50),
79
-
AccountType nvarchar(50),
80
-
UnitSold int,
81
-
82
-
CONSTRAINT uniq_account UNIQUE (AccountKey)
83
-
);
84
-
85
-
--Store the table as a columnstore.
86
-
--The unique constraint is preserved as a nonclustered index on the columnstore table.
87
-
CREATE CLUSTERED COLUMNSTORE INDEX t_account_cci ON t_account
88
-
89
-
--By using the previous two steps, every row in the table meets the UNIQUE constraint
90
-
--on a non-NULL column.
91
-
--This has the same end-result as having a primary key constraint
92
-
--All updates and inserts must meet the unique constraint on the nonclustered index or they will fail.
74
+
--EXAMPLE: Enforce a primary key constraint on a columnstore table.
75
+
76
+
--Create a rowstore table with a unique constraint.
77
+
--The unique constraint is implemented as a nonclustered index.
78
+
CREATETABLEt_account (
79
+
AccountKey intNOT NULL,
80
+
AccountDescription nvarchar (50),
81
+
AccountType nvarchar(50),
82
+
UnitSold int,
83
+
CONSTRAINT uniq_account UNIQUE (AccountKey)
84
+
);
85
+
86
+
--Store the table as a columnstore.
87
+
--The unique constraint is preserved as a nonclustered index on the columnstore table.
88
+
CREATE CLUSTERED COLUMNSTORE INDEX t_account_cci ON t_account;
89
+
90
+
--By using the previous two steps, every row in the table meets the UNIQUE constraint
91
+
--on a non-NULL column.
92
+
--This has the same end-result as having a primary key constraint
93
+
--All updates and inserts must meet the unique constraint on the nonclustered index or they will fail.
93
94
94
-
--If desired, add a foreign key constraint on AccountKey.
95
+
--If desired, add a foreign key constraint on AccountKey.
95
96
96
97
ALTERTABLE [dbo].[t_account]
97
-
WITH CHECK ADD FOREIGN KEY([AccountKey]) REFERENCES my_dimension(Accountkey);
98
-
```
99
-
100
-
### Improve performance by enabling row-level and row-group-level locking
98
+
WITH CHECK ADD FOREIGN KEY([AccountKey]) REFERENCES my_dimension (Accountkey);
99
+
```
100
+
101
+
### Improve performance by enabling row-level and rowgroup-level locking
102
+
103
+
To complement the nonclustered index on a columnstore index feature, [!INCLUDE [sssql16-md](../../includes/sssql16-md.md)] offers granular locking capability for `SELECT`, `UPDATE`, and `DELETE` operations. Queries can run with row-level locking on index seeks against a nonclustered index and rowgroup-level locking on full table scans against the columnstore index. Use this to achieve higher read/write concurrency by using row-level and rowgroup-level locking appropriately.
104
+
105
+
```sql
106
+
--Granular locking example
107
+
--Store table t_account as a columnstore table.
108
+
CREATE CLUSTERED COLUMNSTORE INDEX taccount_cci ON t_account
109
+
110
+
--Add a nonclustered index for use with this example
--Look at locking with access through the nonclustered index
114
+
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
115
+
116
+
BEGIN TRAN
117
+
-- The query plan chooses a seek operation on the nonclustered index
118
+
-- and takes the row lock
119
+
SELECT*
120
+
FROM t_account
121
+
WHERE AccountKey =100;
122
+
COMMIT TRAN;
123
+
```
101
124
102
-
To complement the nonclustered index on a columnstore index feature, [!INCLUDE [sssql16-md](../../includes/sssql16-md.md)] offers granular locking capability for select, update, and delete operations. Queries can run with row-level locking on index seeks against a nonclustered index and rowgroup-level locking on full table scans against the columnstore index. Use this to achieve higher read/write concurrency by using row-level and rowgroup-level locking appropriately.
103
-
104
-
```sql
105
-
--Granular locking example
106
-
--Store table t_account as a columnstore table.
107
-
CREATE CLUSTERED COLUMNSTORE INDEX taccount_cci ON t_account
108
-
GO
109
-
110
-
--Add a nonclustered index for use with this example
--Look at locking with access through the nonclustered index
115
-
SET TRANSACTION ISOLATION LEVEL repeatable read;
116
-
GO
117
-
118
-
BEGIN TRAN
119
-
-- The query plan chooses a seek operation on the nonclustered index
120
-
-- and takes the row lock
121
-
SELECT*FROM t_account WHERE AccountKey =100;
122
-
COMMIT TRAN
123
-
```
124
-
125
125
### Snapshot isolation and read-committed snapshot isolation
126
126
127
-
Use snapshot isolation (SI) to guarantee transactional consistency, and read-committed snapshot isolation (RCSI) to guarantee statement level consistency for queries on columnstore indexes. This allows the queries to run without blocking data writers. This non-blocking behavior also significantly reduces the likelihood of deadlocks for complex transactions. For more information, see [Snapshot Isolation in SQL Server](../../t-sql/statements/set-transaction-isolation-level-transact-sql.md#arguments).
127
+
Use snapshot isolation (SI) to guarantee transactional consistency, and read-committed snapshot isolation (RCSI) to guarantee statement level consistency for queries on columnstore indexes. This allows the queries to run without blocking data writers. This non-blocking behavior also significantly reduces the likelihood of deadlocks for complex transactions. For more information, see [Row versioning-based isolation levels in the Database Engine](../sql-server-transaction-locking-and-row-versioning-guide.md#Row_versioning).
0 commit comments