Skip to content

Commit 1cecb2b

Browse files
Address review comments
1 parent fd3cb56 commit 1cecb2b

File tree

3 files changed

+13
-52
lines changed

3 files changed

+13
-52
lines changed

docs/relational-databases/indexes/columnstore-indexes-data-warehouse.md

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,8 @@ Columnstore indexes, in conjunction with partitioning, are essential for buildin
2525
- Always On availability groups support querying a columnstore index on a readable secondary replica.
2626
- Multiple Active Result Sets (MARS) supports columnstore indexes.
2727
- 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.
28+
- All queries on columnstore indexes can run in batch mode. Previously, only parallel queries could run in batch mode.
29+
- The **Sort**, **Distinct Sort**, and **Distinct** operators run in batch mode.
3130
- Window aggregates now runs in batch mode for database compatibility level 130 and higher.
3231
- Aggregate pushdown for efficient processing of aggregates. This is supported on all database compatibility levels.
3332
- String predicate pushdown for efficient processing of string predicates. This is supported on all database compatibility levels.
@@ -64,38 +63,25 @@ CREATE UNIQUE INDEX taccount_nc1 ON t_account (AccountKey);
6463

6564
### Example: Use a nonclustered index to enforce a primary key constraint on a columnstore table
6665

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.
66+
Because a table can have at most one clustered index, a table with a clustered columnstore index can't have a clustered primary key constraint. To create a primary key constraint on a columnstore table, you must declare it as nonclustered.
6867

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.
68+
The following example creates a table with a nonclustered primary key constraint and then creates a clustered columnstore index on the table. Since any insert or update on the columnstore table also modifies the nonclustered index, all operations that violate the primary key constraint cause the entire operation to fail.
7269

7370
```sql
74-
--EXAMPLE: Enforce a primary key constraint on a columnstore table.
71+
--Create a primary key constraint on a columnstore table.
7572

76-
--Create a rowstore table with a unique constraint.
77-
--The unique constraint is implemented as a nonclustered index.
73+
--Create a rowstore table with a nonclustered primary key constraint.
7874
CREATE TABLE t_account (
7975
AccountKey int NOT NULL,
8076
AccountDescription nvarchar (50),
8177
AccountType nvarchar(50),
8278
UnitSold int,
83-
CONSTRAINT uniq_account UNIQUE (AccountKey)
79+
CONSTRAINT pk_account PRIMARY KEY NONCLUSTERED (AccountKey)
8480
);
8581

86-
--Store the table as a columnstore.
87-
--The unique constraint is preserved as a nonclustered index on the columnstore table.
82+
--Convert the table to columnstore.
83+
--The primary key constraint is preserved as a nonclustered index on the columnstore table.
8884
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.
94-
95-
--If desired, add a foreign key constraint on AccountKey.
96-
97-
ALTER TABLE [dbo].[t_account]
98-
WITH CHECK ADD FOREIGN KEY([AccountKey]) REFERENCES my_dimension (Accountkey);
9985
```
10086

10187
### Improve performance by enabling row-level and rowgroup-level locking

docs/relational-databases/indexes/columnstore-indexes-design-guidance.md

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -196,35 +196,11 @@ Each rowgroup contains one column segment for every column in the table. Each co
196196

197197
There is metadata with each segment to allow for fast elimination of segments without reading them. Data type choices might have a significant impact on query performance based common filter predicates for queries on the columnstore index. For more information, see [segment elimination](columnstore-indexes-query-performance.md#segment-elimination).
198198

199-
## Related Tasks
200-
201-
These are tasks for creating and maintaining columnstore indexes.
202-
203-
| Task | Reference articles | Notes |
204-
| --- | --- | --- |
205-
| Create a table as a columnstore. | [CREATE TABLE (Transact-SQL)](../../t-sql/statements/create-table-transact-sql.md) | By default, when you create a table, it uses rowstore as the underlying data format. Beginning with [!INCLUDE [sssql16-md](../../includes/sssql16-md.md)], you can create the table with a clustered columnstore index by specifying the `INDEX ... CLUSTERED COLUMNSTORE` option. You don't have to first create a rowstore table and then convert it to columnstore. |
206-
| Convert a rowstore table to a columnstore. | [CREATE COLUMNSTORE INDEX (Transact-SQL)](../../t-sql/statements/create-columnstore-index-transact-sql.md) | Convert an existing heap or B-tree to a columnstore. Examples show how to handle existing indexes and also the name of the index when performing this conversion. |
207-
| Create a nonclustered columnstore index on a rowstore table. | [CREATE COLUMNSTORE INDEX (Transact-SQL)](../../t-sql/statements/create-columnstore-index-transact-sql.md) | A rowstore table can have one nonclustered columnstore index. Beginning with [!INCLUDE [sssql16-md](../../includes/sssql16-md.md)], the nonclustered columnstore index can have a filtered condition. Examples show the basic syntax. |
208-
| Convert a columnstore table to a rowstore. | [CREATE CLUSTERED INDEX (Transact-SQL)](../../t-sql/statements/create-columnstore-index-transact-sql.md#d-convert-a-columnstore-table-to-a-rowstore-table-with-a-clustered-index) or [Convert a columnstore table back to a rowstore heap](../../t-sql/statements/create-columnstore-index-transact-sql.md#e-convert-a-columnstore-table-back-to-a-rowstore-heap) | Usually this conversion isn't necessary, but there can be times when you need to convert. Examples show how to convert a columnstore to a heap or clustered index. |
209-
| Create columnstore indexes for data warehousing. | [Columnstore indexes for data warehousing](columnstore-indexes-data-warehouse.md) | Describes how to use columnstore indexes for fast data warehousing queries. |
210-
| Create indexes for operational analytics. | [Get started with columnstore for real-time operational analytics](get-started-with-columnstore-for-real-time-operational-analytics.md) | Describes how to create complementary columnstore and B-tree indexes, so that OLTP queries use B-tree indexes and analytics queries use columnstore indexes. |
211-
| Use a B-tree index to enforce a primary key constraint on a columnstore index. | [Columnstore indexes for data warehousing](columnstore-indexes-data-warehouse.md) | Shows how to combine B-tree and columnstore indexes to enforce the primary key constraint on a columnstore table. |
212-
| Create a memory-optimized table with a columnstore index. | [CREATE TABLE (Transact-SQL)](../../t-sql/statements/create-table-transact-sql.md) | Beginning with [!INCLUDE [sssql16-md](../../includes/sssql16-md.md)], you can create a memory-optimized table with a columnstore index. The columnstore index can also be added after the table is created by using the `ALTER TABLE ADD INDEX` syntax. |
213-
| Load data into a columnstore index. | [Columnstore indexes data loading](columnstore-indexes-data-loading-guidance.md) | |
214-
| Drop a columnstore index. | [DROP INDEX (Transact-SQL)](../../t-sql/statements/drop-index-transact-sql.md) | Dropping a columnstore index uses the standard `DROP INDEX` syntax that B-tree indexes use. Dropping a clustered columnstore index converts the columnstore table to a heap. |
215-
| Delete a row from a columnstore index. | [DELETE (Transact-SQL)](../../t-sql/statements/delete-transact-sql.md) | Use [DELETE (Transact-SQL)](../../t-sql/statements/delete-transact-sql.md) to delete a row.<br /><br />**columnstore row**: [!INCLUDE [ssNoVersion](../../includes/ssnoversion-md.md)] marks the row as logically deleted, but doesn't reclaim the physical storage for the row until the index is rebuilt.<br />**deltastore row**: [!INCLUDE [ssNoVersion](../../includes/ssnoversion-md.md)] logically and physically deletes the row. |
216-
| Update a row in the columnstore index. | [UPDATE (Transact-SQL)](../../t-sql/queries/update-transact-sql.md) | Use [UPDATE (Transact-SQL)](../../t-sql/queries/update-transact-sql.md) to update a row.<br /><br />**columnstore row**: [!INCLUDE [ssNoVersion](../../includes/ssnoversion-md.md)] marks the row as logically deleted and then inserts the updated row into the deltastore.<br />**deltastore row**: [!INCLUDE [ssNoVersion](../../includes/ssnoversion-md.md)] updates the row in the deltastore. |
217-
| Force all rows in the deltastore to go into the columnstore. | [ALTER INDEX (Transact-SQL)](../../t-sql/statements/alter-index-transact-sql.md) ... `REBUILD`<br /><br />[Optimize index maintenance to improve query performance and reduce resource consumption](reorganize-and-rebuild-indexes.md) | `ALTER INDEX` with the `REBUILD` option forces all rows to go into the columnstore. |
218-
| Defragment a columnstore index. | [ALTER INDEX (Transact-SQL)](../../t-sql/statements/alter-index-transact-sql.md) | `ALTER INDEX ... REORGANIZE` defragments columnstore indexes online. |
199+
## Related tasks
219200

220-
## Related content
221-
222-
To create an empty columnstore index for:
201+
For a summary of common tasks for creating and maintaining columnstore indexes, see [Related tasks](columnstore-indexes-overview.md#related-tasks).
223202

224-
- [!INCLUDE[ssNoVersion](../../includes/ssnoversion-md.md)] or [!INCLUDE[ssSDS](../../includes/sssds-md.md)], refer to [CREATE TABLE (Transact-SQL)](../../t-sql/statements/create-table-transact-sql.md).
225-
- [!INCLUDE[ssazuresynapse-md](../../includes/ssazuresynapse-md.md)], refer to [CREATE TABLE (Azure Synapse Analytics)](../../t-sql/statements/create-table-as-select-azure-sql-data-warehouse.md).
226-
227-
For more information on how to convert an existing rowstore heap or B-tree index into a clustered columnstore index, or to create a nonclustered columnstore index, refer to [CREATE COLUMNSTORE INDEX (Transact-SQL)](../../t-sql/statements/create-columnstore-index-transact-sql.md).
203+
## Related content
228204

229205
- [What's new in columnstore indexes](columnstore-indexes-what-s-new.md)
230206
- [Columnstore indexes in data warehousing](columnstore-indexes-data-warehouse.md)

docs/relational-databases/indexes/columnstore-indexes-overview.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,8 +258,7 @@ All of the columns in a columnstore index are stored in the metadata as included
258258
| Drop a columnstore index. | [DROP INDEX (Transact-SQL)](../../t-sql/statements/drop-index-transact-sql.md) | Dropping a columnstore index uses the standard `DROP INDEX` syntax that B-tree indexes use. Dropping a clustered columnstore index converts the columnstore table to a heap. |
259259
| Delete a row from a columnstore index. | [DELETE (Transact-SQL)](../../t-sql/statements/delete-transact-sql.md) | Use [DELETE (Transact-SQL)](../../t-sql/statements/delete-transact-sql.md) to delete a row.<br /><br />**columnstore row**: [!INCLUDE [ssNoVersion](../../includes/ssnoversion-md.md)] marks the row as logically deleted, but doesn't reclaim the physical storage for the row until the index is rebuilt.<br />**deltastore row**: [!INCLUDE [ssNoVersion](../../includes/ssnoversion-md.md)] logically and physically deletes the row. |
260260
| Update a row in the columnstore index. | [UPDATE (Transact-SQL)](../../t-sql/queries/update-transact-sql.md) | Use [UPDATE (Transact-SQL)](../../t-sql/queries/update-transact-sql.md) to update a row.<br /><br />**columnstore row**: [!INCLUDE [ssNoVersion](../../includes/ssnoversion-md.md)] marks the row as logically deleted and then inserts the updated row into the deltastore.<br />**deltastore row**: [!INCLUDE [ssNoVersion](../../includes/ssnoversion-md.md)] updates the row in the deltastore. |
261-
| Force all rows in the deltastore to go into the columnstore. | [ALTER INDEX (Transact-SQL)](../../t-sql/statements/alter-index-transact-sql.md) ... `REBUILD`<br /><br />[Optimize index maintenance to improve query performance and reduce resource consumption](reorganize-and-rebuild-indexes.md) | `ALTER INDEX` with the `REBUILD` option forces all rows to go into the columnstore. |
262-
| Defragment a columnstore index. | [ALTER INDEX (Transact-SQL)](../../t-sql/statements/alter-index-transact-sql.md) | `ALTER INDEX ... REORGANIZE` defragments columnstore indexes online. |
261+
| Maintain a columnstore index. | [ALTER INDEX ... REBUILD](../../t-sql/statements/alter-index-transact-sql.md#rebuild--with--rebuild_index_option---n---)<br /><br />[REORGANIZE a columnstore index](../../t-sql/statements/alter-index-transact-sql.md#reorganize-a-columnstore-index)<br /><br />[Index maintenance methods: reorganize and rebuild](reorganize-and-rebuild-indexes.md#index-maintenance-methods-reorganize-and-rebuild) | In most cases, `ALTER INDEX ... REORGANIZE` provides results similar to `ALTER INDEX ... REBUILD` but with lower resource consumption. `ALTER INDEX ... REORGANIZE` always runs online. Both options defragment a columnstore index and force rows in the deltastore to go into the columnstore.<br /><br />Starting with [!INCLUDE [sql-server-2019](../../includes/sssql19-md.md)], in [!INCLUDE [ssazure-sqldb](../../includes/ssazure-sqldb.md)], and in [!INCLUDE [ssazuremi](../../includes/ssazuremi-md.md)], columnstore index quality is maintained automatically, removing the need for periodic index maintenance in most cases. |
263262

264263
## Related content
265264

0 commit comments

Comments
 (0)