1. Trang chủ
  2. » Công Nghệ Thông Tin

Microsoft SQL Server 2008 R2 Unleashed- P124 pptx

10 268 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 266,16 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

The following example uses ALTER TABLE to reorganize the clustered index on the sales_big table: ALTER INDEX ci_sales_big on sales_big REORGANIZE After running this command, you can run

Trang 1

Listing 34.6 shows examples of running sys.dm_db_index_physical_stats on the

sales_big table, using both LIMITED and DETAILED scan modes

LISTING 34.6 sys.dm_db_index_physical_stats Examples

use bigpubs2008

go

select str(index_id,3,0) as indid,

left(index_type_desc, 20) as index_type_desc,

index_depth as idx_depth,

index_level as idx_level,

str(avg_fragmentation_in_percent, 5,2) as avg_frgmnt_pct,

str(page_count, 10,0) as pg_cnt

FROM sys.dm_db_index_physical_stats

(db_id(), object_id(‘sales_big’),null, 0, ‘LIMITED’)

select str(index_id,3,0) as indid,

left(index_type_desc, 20) as index_type_desc,

index_depth as idx_depth,

index_level as idx_level,

str(avg_fragmentation_in_percent, 5,2) as avg_frgmnt_pct,

str(page_count, 10,0) as pg_cnt

FROM sys.dm_db_index_physical_stats

(db_id(), object_id(‘sales_big’),null, 0, ‘DETAILED’)

go

indid index_type_desc idx_depth idx_level avg_frgmnt_pct pg_cnt

- - -

-1 CLUSTERED INDEX 3 0 63.42 -145 -19

2 NONCLUSTERED INDEX 3 0 14.90 4571

indid index_type_desc idx_depth idx_level avg_frgmnt_pct pg_cnt - - -

-1 CLUSTERED INDEX 3 0 63.42 -145 -19

1 CLUSTERED INDEX 3 1 92.11 38

1 CLUSTERED INDEX 3 2 0.00 1

2 NONCLUSTERED INDEX 3 0 14.90 4571

2 NONCLUSTERED INDEX 3 1 87.50 8

2 NONCLUSTERED INDEX 3 2 0.00 1

Again, you can see from the output in Listing 34.6 that the logical fragmentation

(avg_frgmnt_pct) is 63.42% for the leaf level of the clustered index (idx_level = 0) This

indicates that nearly two thirds of the data pages are out of sequence in relation to

Trang 2

ing of the clustered key values If you want to improve the performance of table scans or

clustered index scans for the sales_big table, you need to decide whether to rebuild the

index or simply defragment the index

The degree of fragmentation helps you decide which defragmentation method to use A

rough guideline to use to help decide is to examine the avg_fragmentation_in_percent

value returned by the sys.dm_db_index_physical_stats function If the

avg_fragmentation_in_percent value is greater than 5% but less than 30%, you should

reorganize the index If the avg_fragmentation_in_percent value is greater than 30%, you

should consider rebuilding the index If you also have a dedicated maintenance window

large enough to perform a rebuild instead of simply reorganizing the index, you may as

well run a rebuild because it performs a more thorough defragmentation than

reorganiz-ing the index

Another factor in determining whether an index needs to be defragmented is how the

data is accessed If your applications are performing primarily single-row lookups,

randomly accessing individual rows of data, the internal or external fragmentation is not a

factor when it comes to query performance Accessing one row from a fragmented table is

just as easy as from an unfragmented table However, if your applications are performing

ordered range scan operations and reading all or large numbers of the pages in a table,

excessive fragmentation can greatly slow down the scan The more contiguous and full the

pages, the better the performance will be of the scanning operations

TIP

If you have very low levels of fragmentation (less than 5%), it is recommended that you

not bother with either a reorganization or a rebuild because the benefit of removing

such a small amount of fragmentation is not enough to justify the cost of reorganizing

or rebuilding the index

In SQL Server 2008, the ALTER INDEX command provides options for defragmenting an

index Following is the syntax for the ALTER INDEX command:

ALTER INDEX { index_name | ALL }

ON [ database_name [ schema_name ] | schema_name ]

table_or_view_name

{ REBUILD

[ [PARTITION = ALL]

[ WITH ( <rebuild_index_option> [ , n ] ) ]

| [ PARTITION = partition_number

[ WITH ( <single_partition_rebuild_index_option>

[ , n ] )

] ]

]

| DISABLE

Trang 3

| REORGANIZE

[ PARTITION = partition_number ]

[ WITH ( LOB_COMPACTION = { ON | OFF } ) ]

| SET ( <set_index_option> [ , n ] )

}

[ ; ]

<rebuild_index_option > ::=

{

PAD_INDEX = { ON | OFF }

| FILLFACTOR = fillfactor

| SORT_IN_TEMPDB = { ON | OFF }

| IGNORE_DUP_KEY = { ON | OFF }

| STATISTICS_NORECOMPUTE = { ON | OFF }

| ONLINE = { ON | OFF }

| ALLOW_ROW_LOCKS = { ON | OFF }

| ALLOW_PAGE_LOCKS = { ON | OFF }

| MAXDOP = max_degree_of_parallelism

| DATA_COMPRESSION = { NONE | ROW | PAGE }

[ ON PARTITIONS ( { <partition_number_expression> | <range> }

[ , n ] ) ]

}

<range> ::=

<partition_number_expression> TO <partition_number_expression>

}

<single_partition_rebuild_index_option> ::=

{

SORT_IN_TEMPDB = { ON | OFF }

| MAXDOP = max_degree_of_parallelism

| DATA_COMPRESSION = { NONE | ROW | PAGE } }

}

<set_index_option>::=

{

ALLOW_ROW_LOCKS = { ON | OFF }

| ALLOW_PAGE_LOCKS = { ON | OFF }

| IGNORE_DUP_KEY = { ON | OFF }

| STATISTICS_NORECOMPUTE = { ON | OFF }

}

The REORGANIZE option is always performed online, regardless of which edition of SQL

Server 2008 you are running, allowing for other users to continue to update and query

the underlying data in the table while the REORGANIZE process is running The REBUILD

option can be executed online only if you are running SQL Server 2008 Enterprise or

Developer Editions In all other editions of SQL Server 2008, the REBUILD option is

Trang 4

executed offline When it is executed offline, SQL Server acquires exclusive locks on the

underlying data and associated indexes so any data modifications to the table are blocked

until the rebuild completes

Reorganizing an index uses minimal system resources to defragment only the leaf level of

clustered and nonclustered indexes of tables and views The first phase of the

reorganiza-tion process compacts the rows on the leaf pages, reapplying the current fill factor value

to reduce the internal fragmentation To view the current fill factor setting, you can run a

query such as the following against the sys.indexes system catalog view:

select cast(name as varchar(30)) as name, index_id, fill_factor

from sys.indexes

where object_id = object_id(‘sales_big’)

go

name index_id fill_factor

-

-ci_sales_big 1 0

idx1 2 0

For more information on fill factor and how to set it, see the “Setting the Fill Factor”

section, later in this chapter

The second phase of the reorganization process involves the rearranging of the leaf-level

pages so that the logical and physical order of the pages match, thereby reducing the

external fragmentation of the leaf level of the index SQL Server 2008 runs a

REORGANIZATION of an index online because the second phase processes only two pages at

a time, in an operation similar to a bubble sort When defragmenting the index, SQL

Server 2008 determines the first physical page belonging to the leaf level and the first

logical page in the leaf level, and it swaps the data on those two pages It then identifies

the next logical and physical page and swaps them, and so on, until no more swaps need

to be made At this point, the logical page ordering matches the physical page ordering

While swapping the logical and physical pages, SQL Server uses an additional new page as

a temporary storage area After each page swap, SQL Server releases all locks and latches

and saves the key of the last moved page

The following example uses ALTER TABLE to reorganize the clustered index on the

sales_big table:

ALTER INDEX ci_sales_big on sales_big REORGANIZE

After running this command, you can run a query similar to the query in Listing 34.6 to

display the fragmentation of the ci_sales_big index on the sales_big table:

select str(s.index_id,3,0) as indid,

left(i.name, 20) as index_name,

left(index_type_desc, 20) as index_type_desc,

index_depth as idx_depth,

index_level as level,

str(avg_fragmentation_in_percent, 5,2) as avg_frgmnt_pct,

Trang 5

str(page_count, 10,0) as pg_cnt

FROM sys.dm_db_index_physical_stats

(db_id(‘bigpubs2008’), object_id(‘sales_big’),1, 0, ‘DETAILED’) s

join sys.indexes i on s.object_id = i.object_id and s.index_id = i.index_id

go

indid index_name index_type_desc idx_depth level avg_frgmnt_pct pg_cnt

- - - -

-1 ci_sales_big CLUSTERED INDEX 3 0 0.32 -145 -19

1 ci_sales_big CLUSTERED INDEX 3 1 92.11 38

1 ci_sales_big CLUSTERED INDEX 3 2 0.00 1

As you can see, the average fragmentation percentage is down to 32% from 63.42%, indi-cating that the index is now mostly defragmented However, the average fragmentation percentage of the intermediate level of the index (level = 1) is still 92.11%, indicating that it is heavily fragmented To defragment the nonleaf levels of the index, you need to rebuild the index The following example shows how to rebuild the index using the ALTER INDEX command: ALTER INDEX ci_sales_big on sales_big REBUILD After running this command, you can again run a query similar to the query in Listing 34.6 to display the fragmentation of the ci_sales_big index on the sales_big table: select str(s.index_id,3,0) as indid, left(i.name, 20) as index_name, left(index_type_desc, 20) as index_type_desc, index_depth as idx_depth, index_level as level, str(avg_fragmentation_in_percent, 5,2) as avg_frgmnt_pct, str(page_count, 10,0) as pg_cnt FROM sys.dm_db_index_physical_stats (db_id(‘bigpubs2008’), object_id(‘sales_big’),1, 0, ‘DETAILED’) s join sys.indexes i on s.object_id = i.object_id and s.index_id = i.index_id go indid index_name index_type_desc idx_depth level avg_frgmnt_pct pg_cnt - - - - -

-1 ci_sales_big CLUSTERED INDEX 3 0 0.0 -1 -14520

1 ci_sales_big CLUSTERED INDEX 3 1 5.26 38

1 ci_sales_big CLUSTERED INDEX 3 2 0.00 1

You can see from these results that the REBUILD option performs a more thorough

defrag-mentation of the ci_sales_big index than REORGANIZE The average fragmentation

percentage of both the leaf and intermediate levels is significantly less

Trang 6

NOTE

When you rebuild a nonclustered index, the rebuild operation requires enough

tempo-rary disk space to store both the old and new indexes However, if the index is disabled

before being rebuilt, the disk space made available by disabling the index can be

reused by the subsequent rebuild or any other operation No additional space is

required except for temporary disk space for sorting, which is typically only about 20%

of the index size

Therefore, if disk space is limited, it may be helpful to disable a nonclustered index

before rebuilding it For more information on disabling indexes, see the “Disabling

Indexes” section, later in this chapter

One of the other options to the CREATE INDEX and ALTER INDEX commands is the

FILLFACTOR option The fill factor allows you to specify, as a percentage, the fullness of the

pages at the data and leaf index page levels, essentially deciding how much free space to

create in the index and data pages to make room for new rows and avoid page splits

Setting the Fill Factor

Fill factor is a setting you can use when creating an index to specify, as a percentage, how

full you want your data pages or leaf-level index pages to be when the index is created A

lower fill factor has the effect of spreading the data and leaf index rows across a greater

number of pages by leaving more free space in the pages This reduces page splitting and

dynamic reorganization of index and data pages, which can improve performance in

envi-ronments where there are a lot of inserts and updates to the data, while at the same time

reducing performance for queries because an increased number of pages need to be read to

retrieve multiple rows A higher fill factor has the effect of packing more data and index

rows per page by leaving less free space in the pages Using a higher fill factor is useful in

environments where the data is relatively static because it reduces the number of pages

required for storing the data and its indexes, and it helps improve performance for queries

by reducing the number of pages that need to be accessed

By default, when you create an index on a table, if you don’t specify a value for

FILLFACTOR, the default value is 0 With a FILLFACTOR setting of 0, or 100, the data pages

for a clustered index and the leaf pages for a nonclustered index are created completely

full However, space is left within the nonleaf nodes of the index for one or two more

rows The default fill factor to be used when creating indexes is a server-level

configura-tion opconfigura-tion If you want to change the server-wide default for the fill factor, you use the

sp_configure command:

sp_configure ‘fill factor’,N

It is generally recommended that you leave the server-wide default for fill factor as 0

and specify your FILLFACTOR settings on an index-by-index basis You can specify a

Trang 7

specific fill factor value for an index by including the FILLFACTOR option for the CREATE

INDEX statement:

CREATE [UNIQUE] [CLUSTERED | NONCLUSTERED] INDEX index_name

ON [ [database_name.][schema_name.]] table_or_view_name

[ WITH ( <relational_index_option> [ , n ] ) ]

<relational_index_option> ::=

{ PAD_INDEX = { ON | OFF }

| FILLFACTOR = fillfactor

| SORT_IN_TEMPDB = { ON | OFF }

| IGNORE_DUP_KEY = { ON | OFF }

| STATISTICS_NORECOMPUTE = { ON | OFF }

| DROP_EXISTING = { ON | OFF }

| ONLINE = { ON | OFF }

| ALLOW_ROW_LOCKS = { ON | OFF }

| ALLOW_PAGE_LOCKS = { ON | OFF }

| MAXDOP = max_degree_of_parallelism }

The FILLFACTOR option for the CREATE INDEX command allows you to specify, as a

percentage, how full the data or leaf-level index pages should be when you create an

index on a table The specified percentage can be from 1 to 100 Specifying a value of 80

would mean that each data or leaf page would be filled approximately 80% full at the

time you create the index It is important to note that as more data gets modified or

added to a table, the fill factor is not maintained at the level specified during the CREATE

INDEX command Over a period of time, you will find that each page has a different

percentage of fullness as rows are added and deleted

TIP

A fill factor setting specified when creating a nonclustered index affects only the

non-clustered index pages and doesn’t affect the data pages To apply a fill factor to the

data pages in a table, you must provide a fill factor setting when creating a clustered

index on the table Also, it is important to remember that the fill factor is applied only

at index creation time and is not maintained by SQL Server When you begin updating

and inserting data, the fill factor is eventually lost Therefore, specifying a fill factor

when creating your indexes is useful only if the table already contains data or if you

simply want to set a default fill factor for the index other than 0 that will be used when

indexes are rebuilt or reorganized by ALTER INDEX

If you specify only the FILLFACTOR option, only the data or leaf-level index pages are

affected by the fill factor To specify the level of fullness for nonleaf pages, use the PAD_INDEX

option together with FILLFACTOR This option allows you to specify how much space to

leave open on each node of the index, which can help to reduce page splits within the

Trang 8

nonleaf levels of the index You don’t specify a value for PAD_INDEX; it uses the same

percentage value specified with the FILLFACTOR option For example, to apply a 50% fill

factor to the leaf and nonleaf pages in a nonclustered index on title_id in the titles

table, you would execute the following:

CREATE INDEX title_id_index on titles (title_id)

with (FILLFACTOR = 50, PAD_INDEX = ON)

TIP

When you use PAD_INDEX, the value specified by FILLFACTOR cannot be such that the

number of rows on each index node falls below two If you do specify such a value,

SQL Server internally overrides it so that the number of rows on an intermediate index

page is never less than two

Reapplying the Fill Factor

When might you need to reestablish the fill factor for your indexes or data? As data gets

modified in a table, the value of FILLFACTOR is not maintained at the level specified in the

CREATE INDEX statement As a result, each page can reach a different level of fullness Over

a period of time, this can lead to heavy fragmentation in the database if insert/delete

activity is not evenly spread throughout the table, and it could affect performance In

addition, if a table becomes very large and then very small, rows could become isolated

within data pages This space will likely not be recovered until the last row on the page is

deleted and the page is marked as unused To either spread out rows or to reclaim space by

repacking more rows per page, you need to reapply the fill factor to your clustered and

nonclustered indexes

In environments where insert activity is heavy, reapplying a low fill factor might help

performance by spreading out the data and leaving free space on the pages, which helps

to minimize page splits and possible page-locking contention during heavy OLTP activity

You can use Performance Monitor to monitor your system and determine whether

exces-sive page splits are occurring (See Chapter 39, “Monitoring SQL Server Performance” for

more information on using Performance Monitor.)

A DBA must manually reapply the fill factor to improve the performance of the system

This can be done by using the ALTER INDEX command discussed earlier or by dropping

and re-creating the index ALTER INDEX is preferred because, by default, it applies the

origi-nal fill factor specified when the index was created, or you can provide a new fill factor to

override the default The original fill factor for an index is stored in sys.indexes in the

fill_factor column In addition, if you use the ALTER INDEX command to reorganize or

rebuild your table or index, it attempts to reapply the index’s original fill factor when it

reorganizes the pages

Trang 9

Disabling Indexes

Another feature available in SQL Server 2008 is the capability to set an index as disabled

When an index is disabled, the definition of the index is maintained in the system catalogs,

but the index itself contains no index key rows Disabling an index prevents user access to

the index Disabling a clustered index also prevents access to the underlying table data

You can manually disable an index at any time by using the ALTER INDEX DISABLE statement:

ALTER INDEX titleidind ON sales DISABLE

The reasons you might want to disable an index include the following:

Correcting a disk I/O or allocation error on an index page and then rebuilding the

index later

Temporarily removing the index for troubleshooting purposes

Saving temporary disk space while rebuilding nonclustered indexes

When you disable an index, the index is not maintained while it is disabled, and the

Query Optimizer does not consider the index when creating query execution plans

However, statistics on a disabled nonclustered index remain in place and are updated

automatically if the AutoStats option is in effect

If you disable a clustered index, all nonclustered indexes on the table are automatically

disabled as well The nonclustered index cannot be re-enabled until the clustered index is

either enabled or dropped After you enable the clustered index, the nonclustered indexes

must be explicitly enabled unless the clustered index was enabled by using the ALTER

INDEX ALL REBUILD statement Because the data rows of the table cannot be accessed while

the clustered index is disabled, the following operations cannot be performed on the table:

SELECT, UPDATE, DELETE, and INSERT

CREATE INDEX

CREATE STATISTICS

UPDATE STATISTICS

ALTER TABLE statements that modify table columns or constraints

After an index is disabled, it remains in a disabled state until it is rebuilt or dropped You

can enable a disabled index by rebuilding it by using one of the following methods:

ALTER INDEX statement with the REBUILD clause

CREATE INDEX with the DROP_EXISTING clause

DBCC DBREINDEX

To determine whether an index is currently disabled, you can use the INDEXPROPERTY

func-tion (a value of 1 indicates the index is disabled):

select indexproperty(object_id(‘sales’), ‘titleidind’, ‘IsDisabled’)

-1

Trang 10

FIGURE 34.27 Setting and viewing index properties in SSMS

Managing Indexes with SSMS

So far, you’ve seen the commands necessary for index management In addition to these

commands, SSMS provides tools for managing indexes

To reorganize or rebuild an index using SSMS, in the Object Explorer, connect to an

instance of the SQL Server 2008 Database Engine and then expand that instance Then

expand Databases, expand the database that contains the table with the specified index,

and expand Tables Next, expand the table in which the index belongs and then expand

Indexes Finally, right-click the index to rebuild and then click Rebuild or Reorganize To

rebuild or reorganize all indexes on a table, right-click Indexes and select Rebuild All or

Reorganize All

You can also disable indexes in SSMS In the Object Explorer, right-click the index you

want to disable and then select the Disable option To disable all indexes on a table,

right-click on Indexes and select Disable All

You can also use SSMS to modify indexes In the Object Explorer, right-click the index you

want to modify and then click Properties In the Properties dialog that appears (see Figure

34.27), you can add or remove columns from the index, change the uniqueness setting,

set the index option, set the fill factor, rebuild the index, view the index fragmentation,

reorganize the index, and so on

Ngày đăng: 05/07/2014, 02:20

TỪ KHÓA LIÊN QUAN