Skip to content

Commit faee0ce

Browse files
Update index fill factor (#36911)
1 parent 027971d commit faee0ce

3 files changed

Lines changed: 77 additions & 65 deletions

File tree

docs/relational-databases/indexes/automatic-index-compaction.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ description: Describes the automatic index compaction feature in the SQL Server
44
author: MikeRayMSFT
55
ms.author: mikeray
66
ms.reviewer: dfurman, randolphwest
7-
ms.date: 03/18/2026
7+
ms.date: 03/19/2026
88
ms.service: sql
99
ms.topic: concept-article
1010
monikerRange: "=azuresqldb-current || =azuresqldb-mi-current || =fabric-sqldb"
@@ -94,7 +94,7 @@ The compaction process might skip some pages because of concurrent activity, suc
9494
- A large PVS size or a large number of aborted transactions to clean up from PVS.
9595
- PVS cleanup is prioritized over automatic compaction. Compaction is suspended if PVS size exceeds 150 GB, or if the number of aborted transactions exceeds 1,000.
9696

97-
For other reasons why the compaction process might skip pages, see [Use an extended event to monitor compaction statistics](#use-an-extended-event-to-monitor-compaction-statistics).
97+
For less common reasons why the compaction process might skip pages, see [Use an extended event to monitor compaction statistics](#use-an-extended-event-to-monitor-compaction-statistics).
9898

9999
If a page is skipped, it's considered for compaction the next time it's processed by the PVS cleaner.
100100

@@ -111,9 +111,10 @@ Consider the following differences between the traditional index maintenance ope
111111
| Considerations | Recommendations |
112112
| --- | --- |
113113
| Compaction occurs continuously and with minimal overhead as long as data in the database is modified. | You don't need to set up, monitor, and maintain index maintenance jobs to gain the benefits that these jobs might provide. |
114-
| Unlike index reorganization and rebuild which process all pages, the compaction process only considers the pages modified after you enable automatic index compaction. | If the page density for an index is already low, consider running a one-time index reorganization or index rebuild to increase it, and then enable automatic compaction to keep indexes compact as future data modifications occur. |
114+
| Unlike index reorganization and rebuild which process all pages, the compaction process only considers the pages modified after you enable automatic index compaction. | If the page density for an index is already low, consider running a one-time index reorganization or index rebuild to increase it. This one-time operation is an extra optimization to increase page density right away. From that point on, automatic compaction keeps indexes compact without any user action. |
115115
| Each index rebuild operation requires a substantial free space in the data files, commonly equal to the size of the index or partition being rebuilt. | You don't need to allocate free space in data files for automatic index compaction or for index reorganization. |
116116
| Unlike index rebuild or index reorganization, compaction doesn't reduce index fragmentation. | Increased page density after compaction is more important than index fragmentation. For most workloads, a higher index fragmentation doesn't affect query performance or resource consumption. |
117+
| When the fill factor for an index is less than 100 percent but the amount of data on a page exceeds the fill factor, neither index compaction nor reorganization move rows away from the page. An index rebuild creates new pages and fills them according to the fill factor. | For most workloads, a higher page density is preferred. Workloads that require a lower fill factor to reduce page splits might benefit from an occasional index rebuild. The rebuild creates pages with a lower page density that matches the fill factor. |
117118
| Unlike index rebuild, compaction doesn't update statistics on the index. | If [automatic statistics update](../statistics/statistics.md#auto_update_statistics-option) is insufficient for your workload and you rely on the [index rebuild to update statistics](reorganize-and-rebuild-indexes.md#a-positive-side-effect-of-index-rebuild), consider using automatic compaction in combination with a statistics update job. |
118119

119120
For more information about index reorganization and rebuild, see [Optimize index maintenance to improve query performance and reduce resource consumption](reorganize-and-rebuild-indexes.md).
@@ -128,7 +129,7 @@ You might observe that index fragmentation is higher when you enable automatic i
128129

129130
| Considerations | Recommendations |
130131
| --- | --- |
131-
| In some write-intensive workloads, pages might split again soon after compaction. Page splits increase index fragmentation. | If workload performance is affected as a result, use a one-time index rebuild with a slightly reduced [fill factor](specify-fill-factor-for-an-index.md) to reduce page splits after compaction.<br /><br />For example, set the fill factor to 95 percent. However, don't reduce the fill factor unnecessarily or set it too low. Most workloads perform optimally with the fill factor set to the default 100 percent. |
132+
| In some write-intensive workloads, pages might split again soon after compaction. Page splits increase index fragmentation. | If workload performance is affected as a result, use a one-time index rebuild with a slightly reduced [fill factor](specify-fill-factor-for-an-index.md) to reduce page splits after compaction.<br /><br />For example, set the fill factor in the 70-95 percent range. However, don't reduce the fill factor unnecessarily or set it too low. Most workloads achieve optimal performance and resource utilization with the fill factor set to the default 100 percent. |
132133
| Deallocating an empty page during compaction can create a gap in the page numbering sequence within an [extent](../pages-and-extents-architecture-guide.md#extents). Gaps within extents increase index fragmentation, potentially reducing the size of [read-ahead](../reading-pages.md#read-ahead) I/O. | Even for workloads that benefit from read-ahead, the performance impact of higher fragmentation is minimized because queries read fewer pages after compaction. |
133134

134135
> [!TIP]
@@ -183,7 +184,7 @@ If a query is blocked, check the command of the head blocker in [sys.dm_exec_req
183184

184185
### Does it honor the fill factor?
185186

186-
Yes. If you specify a non-default [fill factor](specify-fill-factor-for-an-index.md) for an index, auto compaction fills pages according to that fill factor. Otherwise, it uses the default fill factor of 100 percent, which is recommended for most workloads.
187+
Auto compaction never fills a page above the [fill factor](specify-fill-factor-for-an-index.md). However, if a page is already filled above the fill factor by the previous DML statements, then compaction doesn't reduce page density. Pages might remain filled above the fill factor after compaction.
187188

188189
### Does it work if an index uses row or page compression?
189190

docs/relational-databases/indexes/specify-fill-factor-for-an-index.md

Lines changed: 56 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
---
2-
title: "Specify Fill Factor for an Index"
3-
description: Specify Fill Factor for an Index
2+
title: Specify Fill Factor for an Index
3+
description: Specify fill factor for an index
44
author: MikeRayMSFT
55
ms.author: mikeray
6-
ms.date: "02/17/2017"
6+
ms.date: 03/19/2026
77
ms.service: sql
88
ms.subservice: table-view-index
99
ms.topic: how-to
@@ -14,52 +14,61 @@ helpviewer_keywords:
1414
- "page splits [SQL Server]"
1515
monikerRange: "=azuresqldb-current || >=sql-server-2016 || >=sql-server-linux-2017 || =azuresqldb-mi-current || =fabric-sqldb"
1616
---
17-
# Specify Fill Factor for an Index
17+
18+
# Specify fill factor for an index
19+
1820
[!INCLUDE [SQL Server Azure SQL Database Azure SQL Managed Instance FabricSQLDB](../../includes/applies-to-version/sql-asdb-asdbmi-fabricsqldb.md)]
1921

20-
This topic describes what fill factor is and how to specify a fill factor value on an index in [!INCLUDE[ssnoversion](../../includes/ssnoversion-md.md)] by using [!INCLUDE[ssManStudioFull](../../includes/ssmanstudiofull-md.md)] or [!INCLUDE[tsql](../../includes/tsql-md.md)].
21-
22-
The fill-factor option is provided for fine-tuning index data storage and performance. When an index is created or rebuilt, the fill-factor value determines the percentage of space on each leaf-level page to be filled with data, reserving the remainder on each page as free space for future growth. For example, specifying a fill-factor value of 80 means that 20 percent of each leaf-level page will be left empty, providing space for index expansion as data is added to the underlying table. The empty space is reserved between the index rows rather than at the end of the index.
23-
24-
The fill-factor value is a percentage from 1 to 100, and the server-wide default is 0 which means that the leaf-level pages are filled to capacity.
25-
22+
This article describes what fill factor is and how to specify a fill factor value for an index using [!INCLUDE[ssManStudioFull](../../includes/ssmanstudiofull-md.md)] or [!INCLUDE[tsql](../../includes/tsql-md.md)].
23+
24+
The fill factor option is provided for fine-tuning index data storage and performance. When an index is created or rebuilt, the fill factor value determines the percentage of space on each leaf-level page to be filled with data, reserving the remainder on each page as free space for future growth. For example, specifying a fill factor value of 80 means that 20 percent of each leaf-level page will be left empty, providing space for data growth. The empty space is reserved on each page of the index rather than at the end of the index.
25+
26+
The fill factor value is a percentage from 1 to 100, and the server-wide default is 0 which means that the leaf-level pages are filled to capacity.
27+
2628
> [!NOTE]
27-
> Fill-factor values 0 and 100 are the same in all respects.
28-
29-
**In This Topic**
30-
31-
- **Before you begin:**
32-
33-
[Performance Considerations](#Performance)
34-
35-
[Security](#Security)
36-
37-
- **To specify a fill factor in an index, using:**
38-
39-
[SQL Server Management Studio](#SSMSProcedure)
40-
41-
[Transact-SQL](#TsqlProcedure)
42-
43-
## <a name="BeforeYouBegin"></a> Before You Begin
44-
45-
### <a name="Performance"></a> Performance Considerations
46-
47-
#### Page Splits
48-
A correctly chosen fill-factor value can reduce potential page splits by providing enough space for index expansion as data is added to the underlying table. When a new row is added to a full index page, the [!INCLUDE[ssDE](../../includes/ssde-md.md)] moves approximately half the rows to a new page to make room for the new row. This reorganization is known as a page split. A page split makes room for new records, but can take time to perform and is a resource intensive operation. Also, it can cause fragmentation that causes increased I/O operations. When frequent page splits occur, the index can be rebuilt by using a new or existing fill-factor value to redistribute the data. For more information, see [Reorganize and Rebuild Indexes](../../relational-databases/indexes/reorganize-and-rebuild-indexes.md).
49-
50-
Although a low, nonzero fill-factor value may reduce the requirement to split pages as the index grows, the index will require more storage space and can decrease read performance. Even for an application oriented for many insert and update operations, the number of database reads typically outnumber database writes by a factor of 5 to 10. Therefore, specifying a fill factor other than the default can decrease database read performance by an amount inversely proportional to the fill-factor setting. For example, a fill-factor value of 50 can cause database read performance to decrease by two times. Read performance is decreased because the index contains more pages, therefore increasing the disk IO operations required to retrieve the data.
51-
52-
#### Adding Data to the End of the Table
53-
A nonzero fill factor other than 0 or 100 can be good for performance if the new data is evenly distributed throughout the table. However, if all the data is added to the end of the table, the empty space in the index pages will not be filled. For example, if the index key column is an IDENTITY column, the key for new rows is always increasing and the index rows are logically added to the end of the index. If existing rows will be updated with data that lengthens the size of the rows, use a fill factor of less than 100. The extra bytes on each page will help to minimize page splits caused by extra length in the rows.
54-
55-
### <a name="Security"></a> Security
56-
57-
#### <a name="Permissions"></a> Permissions
58-
Requires ALTER permission on the table or view. User must be a member of the **sysadmin** fixed server role or the **db_ddladmin** and **db_owner** fixed database roles.
59-
60-
## <a name="SSMSProcedure"></a> Using SQL Server Management Studio
61-
62-
#### To specify a fill factor by using Table Designer
29+
> Fill factor values 0 and 100 are the same in all respects.
30+
31+
**In This Topic**
32+
33+
- **Before you begin:**
34+
35+
[Performance Considerations](#Performance)
36+
37+
[Security](#Security)
38+
39+
- **To specify a fill factor in an index, using:**
40+
41+
[SQL Server Management Studio](#SSMSProcedure)
42+
43+
[Transact-SQL](#TsqlProcedure)
44+
45+
## <a name="BeforeYouBegin"></a> Before You Begin
46+
47+
### <a name="Performance"></a> Performance Considerations
48+
49+
#### Page splits
50+
51+
When a new row is added to a full index page, the [!INCLUDE[ssDE](../../includes/ssde-md.md)] moves approximately half the rows to a new page to make room for the new row. This reorganization is known as a page split. A page split makes room for new rows, but if it occurs in the middle of the index, it can take time to perform and is a resource intensive operation. Also, it can cause fragmentation that reduces the effectiveness of [page read-ahead](../reading-pages.md#read-ahead) during large index scans.
52+
53+
A well-chosen fill factor value can reduce page splits by providing enough space for index expansion when data is added in the middle of the index. If page splits affect performance, the index can be rebuilt by using a new or existing fill factor value in the 70-95 percent range. However, don't reduce the fill factor unnecessarily or set it too low. For more information, see [Optimize index maintenance to improve query performance and reduce resource consumption](../../relational-databases/indexes/reorganize-and-rebuild-indexes.md).
54+
55+
Most workloads perform optimally with the default 100 percent fill factor. With a reduced fill factor, the index requires more storage space, memory, and disk I/O, which can decrease performance. Even for a write-intensive workload, database reads typically outnumber database writes by a factor of five to ten. Therefore, specifying a fill factor other than the default can increase resource utilization by an amount inversely proportional to the fill factor setting.
56+
57+
For example, a fill factor value of 50 doubles the disk I/O and memory required to read and cache the same amount of data.
58+
59+
#### Data added to the end of the table
60+
61+
A lower fill factor might reduce page splits and improve performance if the new data is evenly distributed throughout the index. However, if new data is added to the end of the index, the empty space in the index pages might not be filled. For example, if the index key column is an `IDENTITY` column, the key for new rows is always increasing and the index rows are logically added to the end of the index.
62+
63+
### <a name="Security"></a> Security
64+
65+
#### <a name="Permissions"></a> Permissions
66+
67+
Requires the `ALTER` permission on the table or view. User must be a member of the `sysadmin` fixed server role or the `db_ddladmin` and `db_owner` fixed database roles.
68+
69+
## <a name="SSMSProcedure"></a> Using SQL Server Management Studio
70+
71+
#### To specify a fill factor by using Table Designer
6372

6473
1. In Object Explorer, click the plus sign to expand the database that contains the table on which you want to specify an index's fill factor.
6574

@@ -136,6 +145,4 @@ monikerRange: "=azuresqldb-current || >=sql-server-2016 || >=sql-server-linux-20
136145
GO
137146
```
138147

139-
For more information, see [ALTER INDEX &#40;Transact-SQL&#41;](../../t-sql/statements/alter-index-transact-sql.md).
140-
141-
148+
For more information, see [ALTER INDEX (Transact-SQL)](../../t-sql/statements/alter-index-transact-sql.md).

0 commit comments

Comments
 (0)