* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Download SAP_R3PerformanceTuningGuide
Survey
Document related concepts
Oracle Database wikipedia , lookup
Tandem Computers wikipedia , lookup
Entity–attribute–value model wikipedia , lookup
Microsoft Access wikipedia , lookup
Ingres (database) wikipedia , lookup
Team Foundation Server wikipedia , lookup
Microsoft Jet Database Engine wikipedia , lookup
Clusterpoint wikipedia , lookup
Open Database Connectivity wikipedia , lookup
Relational model wikipedia , lookup
Database model wikipedia , lookup
Transcript
SAP R/3 Performance Tuning Guide for Microsoft SQL Server 7.0 The information contained in this document represents the current view of Microsoft Corporation on the issues discussed as of the date of publication. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information presented after the date of publication. This document is for informational purposes only. MICROSOFT MAKES NO WARRANTIES, EXPRESS OR IMPLIED, IN THIS DOCUMENT. © 1998 Microsoft Corporation. All rights reserved. Microsoft, MSDN, Windows, and Windows NT are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries. Other product and company names mentioned herein may be the trademarks of their respective owners. Part number: 098-82427 2 Contents Audience ................................................................................................................................................... 5 Introduction ............................................................................................................................................. 6 Windows NT Configurations.................................................................................................................. 7 Virtual Memory Sizing ...................................................................................................................... 7 Optimize Windows NT Server VMM for SQL Server ...................................................................... 7 Optimize Windows NT Desktop ........................................................................................................ 7 Balancing Network Activity on Multiprocessor Servers.................................................................... 8 SQL Server Configurations .................................................................................................................. 10 Memory Sizing................................................................................................................................. 10 set working set size Option .............................................................................................................. 10 network packet size Option .............................................................................................................. 10 priority boost Option ........................................................................................................................ 11 index create memory Option ............................................................................................................ 11 Disable Page Locks on VBHDR, VBMOD, and VBDATA ............................................................ 11 lightweight pooling Option .............................................................................................................. 11 affinity mask Option ........................................................................................................................ 12 Index Design and Maintenance ............................................................................................................ 13 Designing Indexes for Best Performance ......................................................................................... 13 Identifying the Queries to Analyze .................................................................................................. 14 Index Analysis Example .................................................................................................................. 14 Sample Data .............................................................................................................................. 14 Sample Indexes ......................................................................................................................... 15 Sample Queries ......................................................................................................................... 15 Reporting Query I/O Statistics in SQL Server Query Analyzer ............................................... 15 Results with First Set of Indexes............................................................................................... 16 Single Row Fetch: select * from saptest1 where col3 = 5000 ........................................... 16 Range Scan: select * from saptest1 where col2 = 'a' .......................................................... 17 Suggested Index Changes ......................................................................................................... 19 Results with Second Set of Indexes .......................................................................................... 20 Single Row Fetch with Improved Index: select * from saptest1 where col3 = 5000 .............................................................................................................................. 20 Range Scan with Improved Index: select * from saptest1 where col2 = 'a' ....................... 21 Observations and Conclusions from Index Analysis ................................................................ 22 Nonclustered Index Contains Clustering Key .................................................................................. 22 Example of a Covered Query Involving the Clustering Key ............................................. 22 sp_recompile .................................................................................................................................... 23 Update Statistics ............................................................................................................................... 24 DBCC SHOWCONTIG ................................................................................................................... 25 FillFactor .......................................................................................................................................... 26 File and Filegroup Design ..................................................................................................................... 28 File Sizing and Use of AutoGrow .................................................................................................... 28 Transaction Log Sizing .................................................................................................................... 28 tempdb Sizing .................................................................................................................................. 28 3 Finding More information .................................................................................................................... 29 4 Audience The information presented in this document is designed to help SAP R/3 database administrators understand aspects of Microsoft® SQL Server™ 7.0. These aspects can be tuned to help provide maximum performance under workload conditions that are characteristics of database workloads associated with the SAP R/3 environment. While this document is tailored to SAP R/3 sites, it is important to note that the SQL Server functionality and tuning techniques described in this document are not just applicable to SAP R/3. Database administrators who work on large to very large databases (VLDB), which need to support a high number of user connections and large workloads, will benefit from reviewing the information in this document. 5 Introduction This performance-tuning document discusses optimal configuration of SQL Server 7.0 for the SAP R/3 environment. The guide is organized into four logical sections. First, there is a discussion of the configuration options to consider for Microsoft Windows NT® Server. The second section describes configuration options that are important for SQL Server in the SAP R/3 environment. These first two sections are straightforward and contain steps that can be completed in a few minutes during initial SQL Server configuration. The third section discusses SQL Server index design as it pertains to SAP R/3. Index analysis tends to be a much more involved process that will need to be performed on an ongoing basis for best database performance. The Microsoft SQL Server 7.0 Performance Tuning Guide, which is available from http://msdn.microsoft.com/developer/sqlserver/sql7perftune.htm, should be considered companion reading to this third section. It discusses hardware I/O performance, index design, and SQL Server performance tuning tools in combination. The fourth section discusses optimal use of SQL Server files and filegroups in the R/3 database environment. 6 Windows NT Configurations Virtual Memory Sizing The Windows NT page file should be sized at least three times larger than the amount of RAM installed on the server and be at least 1 gigabyte (GB). To set the page file size 1. On the Start menu, point to Settings, and then click Control Panel. 2. Double-click System, and then double-click the Performance tab. 3. Click Change, and then in the Initial Size (MB) box, enter the size of the paging file in megabytes (MB). 4. Click OK. Optimize Windows NT Server VMM for SQL Server Usually, the VMM (Virtual Memory Manager) is already configured properly by the default setting for SQL Server installation. To check and/or configure VMM setting 1. On the Start menu, point to Settings, and then click Control Panel. 2. Double-click Network, and then click the Services tab. 3. Double-click Server, select the Maximize Throughput for Network Applications, and then click OK. Optimize Windows NT Desktop To configure minimal impact screensaver and wallpaper 1. On the Start menu, point to Settings, and then click Control Panel. 2. Double-click Display, and then click the Background tab. 3. Select (None) for Pattern and (None) for Wallpaper. 4. Click Apply, and then click the Screen Saver tab. 5. Under Screen Saver, select Blank Screen, and then select Password Protection. 6. Click Apply. 7 Balancing Network Activity on Multiprocessor Servers Some multiple-processor servers can dynamically distribute networking I/O requests to the least busy processor. This hardware feature is helpful in preventing processor bottlenecks and poor network performance in systems that service many networking requests. This feature is often referred to as symmetric interrupt distribution and is designed to improve scaling and to prevent a single processor from becoming a bottleneck while other processors have excess capacity. It is available on the Windows NT 4.0 HAL (Hardware Abstraction Layer) for the Pentium family of processors. This functionality will also be supported in Windows ® 2000. Different processor platforms use different methods to distribute interrupts. The distribution of interrupts from network adapter cards is controlled by the HAL for each processor platform. The interrupt scheme implemented by the HAL depends on the capability of the processor. Some processors include interrupt control hardware, such as the Advanced Programmable Interrupt Controller (APIC). The APIC allows processors to route interrupts to other processors on the computer. For more information about the distribution method used for a specific processor platform, consult with that platform’s vendor. In the default case, Windows NT 4.0 does not take advantage of symmetric interrupt distribution and assigns deferred process call (DPC) activity associated with network adapter cards (NICs) to the highest numbered processor in the system. In systems with more than one installed and active NIC, each additional NIC’s activity is assigned to the next highest numbered processor. If a processor frequently operates at capacity (indicated in Performance Monitor Processor: % Processor Time = 100%) and more than half of its time is spent servicing DPCs (if Processor: % DPC Time > 50%), it is possible to improve the performance by adjusting ProcessorAffinityMask. Warning: Using Registry Editor incorrectly can cause serious problems that may require reinstallation of the operating system. Use Registry Editor very carefully. Microsoft cannot guarantee that problems resulting from the incorrect use of Registry Editor can be solved. It is recommended that you back up the contents of the registry prior to performing modifications so that the contents can be restored in case of problems with registry modifications. Instructions for backing up and restoring registry information can be found in the online help of Registry Editor. On a multiprocessor server that is capable of symmetric interrupt distribution, set the value of the ProcessorAffinityMask value entry in the Windows NT registry to zero. This distributes the network I/O requests dynamically to the processor that has the most capacity to process the request. ProcessorAffinityMask is located in: HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NDIS\Parameters. 8 To start the Registry Editor to set ProcessorAffinityMask 1. On the Start menu, click Run. 2. Type regedt32. To find the appropriate key in the Registry Editor 1. On the Window menu, select HKEY_LOCAL_MACHINE. 2. In the left pane of Registry Editor, double-click System. 3. Double-click CurrentControlSet, double-click Services, double-click NDIS, and then double-click Parameters. To enter zero for ProcessorAffinityMask 1. In the right pane of Registry Editor, double-click ProcessorAffinityMask. 2. Type 0 (zero), and then click OK. 3. On the Registry menu, click Exit. 9 SQL Server Configurations Memory Sizing The recommended settings for SQL Server memory depend upon the usage of the database server by the R/3 instance. With SQL Server running as a dedicated database server, it is recommended that SQL Server dynamically adjust the memory it requires, which is the default. R/3 Instance Minimum Value Maximum Value Dedicated database server Default Default Update Instance 40 percent of installed RAM 65 percent of installed RAM Central Instance 45 percent of installed RAM 45 percent of installed RAM Example of setting memory on a Central Instance with 2 GB of RAM (Enterprise Manager) 1. In the right pane, double-click the SQL Server Group icon. 2. Double-click the SQL Server icon for the R/3 database server. 3. Click the Memory tab, and then click Use a fixed memory size (MB). 4. Move the slider under Use a fixed memory size (MB) to 900. 5. Select Reserve physical memory for SQL Server, click Apply, and then click OK. set working set size Option After memory has been configured for SQL Server, it is recommended that the set working set size option be used to reserve physical memory space for SQL Server that is equal to the SQL Server memory setting. Setting this option means that Windows NT does not swap out SQL Server pages. Example of configuring the set working set size option (Enterprise Manager) 1. In the right pane, double-click the SQL Server Group icon. 2. Double-click the SQL Server icon for the R/3 database server. 3. Click the Memory tab, and then select Reserve physical memory for SQL Server. 4. Click Apply, and then click OK. network packet size Option SAP testing has indicated that a network packet size of 8,192 bytes is optimal for performance under most R/3 database server operating environments. This option needs to be set using SQL Server Query Analyzer. 10 To set network packet size (Query Analyzer) 1. Type exec sp_configure ‘network packet size’, 8192. 2. Type reconfigure with override. 3. Press CTRL + E to execute the above commands. priority boost Option On dedicated database servers, it is recommended that the SQL Server priority boost option be used. To set the priority boost option (Enterprise Manager) 1. In the right pane, double-click the SQL Server Group icon. 2. Double-click the SQL Server icon for the R/3 database server. 3. Click the Processor tab, and then in the Processor Control box, select Boost SQL Server priority on Windows NT. index create memory Option It is recommended that SQL Server index create memory option be configured to 16 MB. This option needs to be set using SQL Server Query Analyzer. To set the index create memory option (Query Analyzer) 1. Type exec sp_configure ‘index create memory’, 16000. 2. Type reconfigure with override. 3. Press CTRL + E to execute the above commands. Disable Page Locks on VBHDR, VBMOD, and VBDATA To disable page locks on tables VBHDR, VBMOD and VBDATA (Query Analyzer) 1. Type the following commands in the Query window: exec sp_indexoption 'VBHDR','allowpagelocks','false' exec sp_indexoption 'VBMOD','allowpagelocks','false' exec sp_indexoption 'VBDATA','allowpagelocks','false' 2. Press CTRL + E to execute the above commands. lightweight pooling Option If all of the processors on the database server are being very highly utilized (Performance Monitor indicates that Processor Utilization for all processors on the multiple-processor server are consistently greater than 95 percent), it is worthwhile to turn on SQL Server lightweight pooling. lightweight pooling can help recover from approximately 5 through 7 percent CPU when all processors are very close to being fully utilized. 11 To turn on SQL Server lightweight pooling (Enterprise Manager) 1. In the right pane, double-click the SQL Server Group icon. 2. Double-click the SQL Server icon for the R/3 database server. 3. Click the Processor tab, select Use Windows NT Fibers, and then click Apply. 4. When prompted to restart SQL Server, click Yes, and then click OK. affinity mask Option The SQL Server affinity mask configuration option provides for the specification of specific processors on which SQL Server threads can not execute. It is best to take advantage of the default setting for SQL Server affinity mask, which is zero. The zero setting for affinity mask indicates that SQL Server threads are allowed to execute on all processors. In almost all situations, best performance results from this setting because it avoids trapping very busy SQL Server connections on a single processor while there is excess capacity available on other processors. Microsoft’s IT organization and SAP R/3 customers participating in the SQL Server 7.0 Early Adopter’s program have made use of the default setting for affinity mask with good performance results. 12 Index Design and Maintenance Designing Indexes for Best Performance The Microsoft SQL Server 7.0 Performance Tuning Guide provides important information about SQL Server indexes and performance tuning. The document should be obtained from the location in “Finding More Information.” Large SAP R/3 installations will have some SQL Server tables that contain a very large number of rows. With large tables, indexes have a large effect on database I/O performance. Operations, which search and operate upon a single database row or small number of database rows, should have a nonclustered or clustered index defined upon the column or columns that provide the highest level of selectivity. This is so that the SQL Server query processor and storage engine can minimize the I/O required to retrieve the rows. For example, if a single order record must be retrieved regularly from a very large Orders table based on the orderid, it would make sense to define an index on the orderid column to speed up the query. Operations which search and operate upon a large number of database rows, should have a clustered index defined upon the column which defines the range scan. An example of a range scan would be a query that retrieves all orders from a very large Orders table for the month of July. In this case, the date column of the Orders table would be the best column for the clustered index. The upcoming 4.5B release of SAP R/3 will have an important feature that effects the flexibility of SQL Server clustered index selection. In the 4.5B release, there will be passive support in the R/3 Data Dictionary for clustered indexes on columns besides primary key columns. Passive support means that the SAP R/3 Data Dictionary will recognize and remember the location of a SQL Server clustered index if a database table is altered such that the clustered index is moved from the primary key to another column or set of columns. The creation of the clustered index needs to be done with SQL Server tools versus R/3 tools. But the location of the clustered index after it is created will not be lost during database conversions and R/3 version upgrades. Future versions of SAP R/3 following 4.5B will likely contain active support for SQL Server clustered indexes. Active support means that R/3 tools will support the creation of clustered indexes on SQL Server tables on columns besides the primary key columns in addition to the support by the R/3 Data Dictionary as described earlier. These changes in clustered index support have important ramifications for R/3 database administrators that are looking to improve the performance of their R/3 reporting queries. Month-end and quarterly reports for large companies running SAP R/3 will likely employ range scans on the database server. Often, it may be the case that the range scan being performed on a large table will not based upon the same columns that define the primary key of the table. Currently, SAP R/3 SQL Server database implementation configures the primary keys on all tables to be a clustered primary key. There may be situations where it is very advantageous to test the use of a clustered index on a column that is not part of the primary key and is frequently used on a large table for reporting purposes. The ALTER TABLE command is used to change a primary key from clustered to nonclustered. 13 The following index analysis example discusses a scenario where it would make sense to change a clustered primary key to be a nonclustered primary key so that the clustered index can be defined on another column and walk through the steps involved in changing a clustered primary key to a nonclustered primary key. The Microsoft SQL Server 7.0 Performance Tuning Guide should be reviewed for more details about clustered and nonclustered index selection. Identifying the Queries to Analyze SAP R/3 provides the MSSTATS tool within transaction ST04 to help R/3 database administrators track the resource consumption of SQL Server stored procedures being executed on the database server. All normal R/3 interactions with the database server are performed using stored procedures. MSSTATS provides information that helps differentiate stored procedures based on resource usage. Examples of the information that MSSTATS returns includes the number of times a stored procedure is called, average and maximum amount of time spent calling stored procedures, average and total rows returned from stored procedure calls, whether or not cursors were used by a stored procedure, time spent fetching versus idle for the stored procedures and more. MSSTATS provides an important tool for identifying the most costly stored procedures running on a R/3 database server. Performance analysis should be focused on these most costly queries. Index Analysis Example The following SQL Server table example is designed to resemble a data pattern very similar to many SAP R/3 tables. Two sample queries will be analyzed using this test table. The goal is to demonstrate how to take best advantage of SQL Server indexes in the R/3 database server environment. Sample Data The following script creates a table called saptest1 and loads 100,000 records into it. The first column named col1 has no selectivity. Every row has the same value for col1 (‘000’). This is designed to simulate the very common MANDT column in SAP R/3 which is usually not very selective. The second column named col2 is designed to have some selectivity because a value of ‘a’ is inserted every one hundred rows. The SQL Server modulo (‘%’) operator is used to detect every one hundredth row insert. The final column named col3 is a very high selectivity. Every row has a unique value for col3. To create the sample data (Query Analyzer) 1. Type the following commands in the Query window: create table col1 char(4) col2 char(4) col3 int not saptest1 ( not null default '000', not null default 'zzzz', null, filler char(300) default 'abc' ) declare @counter int set nocount on 14 set @counter = 1 while (@counter <= 100000) begin if (@counter % 1000 = 0) PRINT 'loaded ' + CONVERT (VARCHAR(10),@counter) + ' of 100000 record' if (@counter % 100 = 0) begin insert saptest1 (col2,col3) values ('a',@counter) end else insert saptest1 (col3) values (@counter) set @counter = @counter + 1 end 2. Press CTRL + E to execute the commands. Sample Indexes SAP R/3 default configuration for SQL Server primary keys is to make the primary key a clustered primary key. This provides excellent performance in most situations. But there may be some isolated tables that would benefit greatly from placing the clustered index on a column besides the columns that comprise the primary key for the table. The clustered primary key column defined for saptest1 is typical of R/3 database environment because it places the completely nonselective column col1 (which is modeled after the MANDT in typical R/3 environments) in the beginning of the index. The nonclustered index nkey2 is modeled after typical R/3 indexes in that it is a multiple column index. To create the sample indexes (Query Analyzer) 1. Type the following commands in the Query window: alter table saptest1 add constraint sapt_c1 PRIMARY KEY clustered (col1,col2,col3) create index nkey2 on saptest1(col2,col3) 2. Press CTRL + E to execute the commands. Sample Queries select * from saptest1 where col3 = 5000 Query 1 fetches a single row from the test table based on a matching value for the column named col3: select * from saptest1 where col2 = 'a' Query 2 is a range scan that fetches 1,000 rows from the table based on a matching value for the column named col2. Reporting Query I/O Statistics in SQL Server Query Analyzer SQL Server Query Analyzer has the capability of providing valuable I/O statistics from each query executed in the Query Window. This is commonly referred to in the SQL Server 15 documentation as Statistics IO. To enable this functionality, you can either execute a T-SQL command or set Query Analyzer menu options. To use the SET STATISTICS IO option via T-SQL command (Query Analyzer) 1. Type the following command in the Query window: set statistics io on 2. Press CTRL + E to execute the command. To use the SET STATISTICS IO option via menu options (Query Analyzer) 1. On the Query Analyzer menu, click Query, and then click Current Connection Options. 2. Select Show Stats I/O and then click Apply. 3. Click OK. Results with First Set of Indexes Single Row Fetch: select * from saptest1 where col3 = 5000 Text-based ShowPlan output: |--Bookmark Lookup(BOOKMARK:([Bmk1000]), OBJECT:([pubs].[dbo].[saptest1])) |--Index Scan(OBJECT:([pubs].[dbo].[saptest1].[nkey2]), WHERE:([saptest1].[col3]=5000)) Equivalent graphical showplan output. 16 Query resultset and database I/O from Stats I/O (Query Analyzer): col1 col2 col3 000 a 5000 (1 row(s) affected) filler abc Table 'saptest1'. Scan count 1, logical reads 240, physical reads 0, read-ahead reads 0. The Showplan output indicates that the query processor needed to perform an index scan of the nonclustered index nkey2. An index scan means that SQL Server needed to read part or all of the leaf level of the nkey2’s B-tree structure in order to find the key value 5000. This operation required 240 I/Os out of the SQL Server data cache. That means 240 8 KB pages had to be read from the SQL Server buffer cache. The zeros indicated for physical reads and read-ahead reads indicated that it was not necessary to read from disk to retrieve the data for this query. Note: The I/O statistics are run-specific. While on one run of a query, all reads may come out of buffer cache and be counted as logical reads, on other runs, it may be possible that the exact same query needs to use read-ahead reads and/or physical reads to statisfy the I/O requirements of the query. This fluctuation in I/O statistics may be due to many factors, the most common of which is the fact that other connections may be performing queries and bringing data into the buffer cache which displace data pages being used by the monitored query. When analyzing queries, it is helpful to run the query several times with I/O statistics turned on and compare the results. The percentages indicated in the Graphical Showplan labeled Cost indicate the amount of time spent on each particular part of the query as a percentage of the total time spent executing the query. Range Scan: select * from saptest1 where col2 = 'a' Text-based ShowPlan output: |--Clustered Index Scan(OBJECT:([pubs].[dbo].[saptest1].[sapt_c1]), WHERE:([saptest1].[col2]='a')) 17 Equivalent graphical showplan output: Query resultset and database I/O from Stats I/O (Query Analyzer): col1 000 000 000 . . . 000 000 000 col2 a a a col3 100 200 300 filler abc abc abc a a a 99800 99900 100000 abc abc abc (1000 row(s) affected) Table 'saptest1'. Scan count 1, logical reads 4500, physical reads 1, read-ahead reads 4010. 18 The Showplan output indicates that the query processor needed to perform an index scan of the clustered index sapt_c1. An index scan means that SQL Server needed to read all or part of the leaf level of sapt_c1’s B-tree structure (which are the actual rows of the table) in order to find the key values ‘a’. This operation required 4,500 8K pages to be read from the buffer cache. The read-ahead reads of 4010 indicates that SQL Server read in 4,010 8 KB pages in 64 KB chunks using the Read-Ahead Manager. Read-ahead reads are more efficient that physical reads. The physical reads of 1 indicates that SQL Server needed to read one 8 KB page as a single 8 KB page from disk. Because they are both physical disk reads, read-ahead reads and physical reads are much slower than logical reads, which are reads from buffer cache. That is why it should be your primary performance tuning goal to limit physical disk reads and try to satisfy all database page reads from buffer cache. Suggested Index Changes The goal of index design is to minimize I/O to maximize performance. In the examples shown earlier, index scans occur. It is more efficient to perform index seeks versus index scans. To make this happen, it is important to focus attention on the WHERE clauses of the queries. In the single row fetch case, col3 is the column being searched on. Because col3 has excellent selectivity, it is a good candidate for a nonclustered index. It is best for I/O performance if the nonclustered is defined on col3 such that col3 is either the only column or the first in the index. In the range scan case, col2 is the column being searched on. Col2 has ok selectivity (1,000 rows out of 100,000 with the value of ‘a’). Because all of the ‘a’ rows are required, col2 is a good candidate for the clustered index. The ALTER TABLE statement is used to change a clustered primary key to a nonclustered primary key. Warning: Do not change the columns that are associated with the primary key of a table under any circumstances. It is all right to change a clustered primary key to a nonclustered primary key and it is all right to create new nonclustered indexes on columns that are also part of the primary key if the performance benefits warrant the change but the primary key columns must remain the same under all circumstances. This is extremely important to remember. Note: In the SAP R/3 environment, it is recommended that transaction SE11 be used to define nonclustered, nonprimary key indexes so that the index information is maintained in the R/3 Data Dictionary. For more information about index creation using transaction SE11, see the SAP online Help accessed from transaction SE11 on the menu item Help -> Extended Help. Click Indexes, and then follow the online instructions. 1. To execute index changes (Query Analyzer) Type the following commands in the Query window: alter table saptest1 drop constraint sapt_c1 alter table saptest1 add constraint sapt_c1 PRIMARY KEY NONCLUSTERED (col1,col2,col3) create clustered index ckey1 on saptest1(col2) create index nkey1 on saptest1(col3) 2. Press CTRL + E to execute the commands. 19 Results with Second Set of Indexes Single Row Fetch with Improved Index: select * from saptest1 where col3 = 5000 Text-based ShowPlan output: |--Bookmark Lookup(BOOKMARK:([Bmk1000]), OBJECT:([pubs].[dbo].[saptest1]) WITH PREFETCH) |--Index Seek(OBJECT:([pubs].[dbo].[saptest1].[nkey1]), SEEK:([saptest1].[col3]=5000) ORDERED) Equivalent graphical showplan output. Query resultset and database I/O from Stats I/O (Query Analyzer): col1 col2 col3 000 a 5000 filler abc (1 row(s) affected) Table 'saptest1'. Scan count 1, logical reads 5, physical reads 0, read-ahead reads 0. Showplan is now indicating that the SQL Server is using an index seek on index nkey1 versus an index scan. An index seek means that SQL Server was able to navigate the nkey1 B-tree structure quickly (versus scanning the leaf level of the index as was the case earlier) and use a bookmark lookup to find the data row associated with the key value of 5000. This change from index scan to index seek has a large effect on I/O performance. Only 5 I/Os from SQL Server data cache were required to execute the query as compared to 240 I/Os in the earlier case. 20 Range Scan with Improved Index: select * from saptest1 where col2 = 'a' Text-based ShowPlan output: |--Clustered Index Seek(OBJECT:([pubs].[dbo].[saptest1].[ckey1]), SEEK:([saptest1].[col2]='a') ORDERED) Equivalent graphical showplan output. Query resultset and database I/O from Stats I/O (Query Analyzer): col1 000 000 000 . . . 000 000 000 col2 a a a col3 100 200 300 filler abc abc abc a a a 99800 99900 100000 abc abc abc (1000 row(s) affected) Table 'saptest1'. Scan count 1, logical reads 48, physical reads 0, read-ahead reads 0. 21 Again, showplan is indicating that the SQL Server is using an index seek on index ckey1 versus an index scan. In the case of clustered index seeks, no bookmark lookup is required because the leaf level of the clustered index B-tree already contains the table data. Once again the change from index scan to index seek has a significant and positive impact on I/O performance. Only 48 reads from SQL Server buffer cache were required to fetch the 1,000 rows as compared to 4,500 I/Os in the earlier case. The I/Os have been reduced dramatically, therefore, no physical disk I/O was required to complete this query because the required pages were already present in the SQL Server data cache. This is indicated by the fact that both physical reads and read-ahead reads are zero. Remember that read-ahead reads are physical disk reads that are 64 KB per read and physical reads refer to physical disk reads that are 8 KB per read. Observations and Conclusions from Index Analysis What should be clear from the earlier example is that index design plays a large part in the I/O performance of SQL Server queries. The range scan example in particular was designed to illustrate that there may be scenarios in your R/3 environment that may lend themselves to a clustered index on columns besides the primary key columns. This is particularly likely for large tables on which reporting is performed. For example, if a large table is used for reporting based on a date column, but the date column is not included in the clustered primary key, it may be very beneficial to test the use of the date column for the clustered index. Nonclustered Index Contains Clustering Key In SQL Server 7.0, the more columns and bytes that are included in the clustered index, the bigger the nonclustered indexes for that particular table become. This is because the column(s) that form the clustered index are used not only by the clustered index but also by the nonclustered indexes for that table. Nonclustered indexes contain the clustering key and use the clustering key to locate rowdata. If there is no clustered index on a table, this situation does not apply. Instead the table is managed as a heap. For more information, see SQL Server Books Online. There are two implications to be aware of now that nonclustered indexes contain the clustering keys within the nonclustered B-tree structures. First, it is important to keep the size of the clustered index smaller because it affects not only the size and performance of the clustered index but also of all of the nonclustered indexes for that table. Second, it is useful to remember that nonclustered indexes contain the clustering key because that key value column can be used by the query processor to help cover queries if the nonclustered index contains all of the columns required to satisfy a query except the clustering key. Example of a Covered Query Involving the Clustering Key The following is a simple example, which shows that if the clustering key contains the only other information that the nonclustered index requires to cover a given query, the query processor uses the nonclustered index as a covering index and does not need to use bookmark lookups to fetch data from the table. For more information about covered queries and index design, see Microsoft SQL Server 7.0 Performance Tuning Guide. 22 Build the following table (Query Analyzer) 1. Type the following commands in the Query window: create table saptest2 (col1 int, col2 char(4) default 'a', filler char(300) default 'zzzz') declare @counter int set @counter = 1 while (@counter <= 1000) begin insert saptest2 (col1) values (@counter) set @counter = @counter + 1 end insert saptest2 values (1001,'sap','R/3') create clustered index sap_CK1 on saptest2(col1) create nonclustered index sap_NCK1 on saptest2(col2) 2. Press CTRL + E to execute the commands. Display and compare the following two query plans (Query Analyzer) 1. Type the following commands in the Query window: select * from saptest2 where col2 = 'sap' select col1,col2 from saptest2 where col2 = 'sap' 2. Select each query separately, and then press CTRL + L to display the graphical showplan. With the second query, a bookmark lookup was not required because the nonclustered index contains the clustering key implicitly and hence, covers the query. sp_recompile When trouble-shooting long-running R/3 processes, one potential action item to keep in mind is the use of sp_recompile to mark stored procedures for recompilation quickly. The sp_recompile command takes very little time to execute and can be very helpful. The sp_recompile command marks the stored procedure quickly so that a new query plan is generated for the stored procedure, one that reflects the most current state of the table’s data, indexes and statistics. Note: Under most normal R/3 operating conditions, there is no need to run sp_recompile because SQL Server recompiles store procedures automatically when it is advantageous to do so. But there have been circumstances in the R/3 environments, where SAP and Microsoft have observed very positive benefit to running sp_recompile on tables that have long running and poorly performing update and batch processes running on them. One of the most convenient ways to use sp_recompile is to submit the table name as the parameter for the command. This will mark for recompilation, all stored procedures associated with the table name. For example, if CCMS reveals that update processes operating on the table VBRP are taking an unusually long time to execute, it is worthwhile to run sp_recompile on the table. 23 Example of executing sp_recompile (Query Analyzer) 1. Type exec sp_recompile ‘VBRP’. 2. Press CTRL + E to execute the command. Update Statistics SQL Server 7.0 provides automatic generation and maintenance of column and index statistics. Statistics assist the query processor in determining optimal query plans. By default, there are statistics created for all indexes, and SQL Server creates single column statistics automatically when compiling queries for columns where column statistics would be useful and the optimizer would have to guess them. To avoid long term maintenance of unused statistics, SQL Server ages the automatically created statistics (only those that are not a byproduct of the index creation). After several automatic updates, the column statistics are dropped rather than updated. If they are needed in the future, they may be created again. There is no substantial cost difference between statistics update and create. This aging does not affect user created statistics. It is recommended that automatic statistics be used for best performance. Automatic statistics creation and update are the default configuration for SQL Server 7.0. The only exceptions to this recommendation are the tables VBHDR, VBMOD and VBDATA. For these tables, it is recommended that automatic statistics be turned off. VBHDR, VBMOD and VBDATA are very dynamic in nature, which means that they may change from being empty to becoming very large, then dropping to empty again on a frequent basis. R/3 access to these tables is done only with the primary keys. Additional statistics on these tables will not be helpful because the same query plan using the primary key is used for every access. It is for these reasons that it is advantageous to turn off automatic statistics on these tables. The following set of commands will prevent any future generation of statistics on the tables VBHDR, VBMOD, and VBDATA. To turn off automatic statistics for VBHDR, VBMOD, and VBDATA (Query Analyzer) 1. Type the following commands in the Query window: exec sp_autostats VBHDR,'OFF' exec sp_autostats VBMOD,'OFF' exec sp_autostats VBDATA,'OFF' 2. Press CTRL + E to execute the commands. Existing statistics on the VBHDR, VBMOD, and VBDATA tables can be deleted from the database with the following commands. To drop existing statistics (Query Analyzer) 1. Use the sp_helpindex command to figure out the name of the statistics to drop. For example, to display the names of any existing statistics on the VBMOD, type the following commands in the Query window: exec sp_helpindex VBMOD 2. Press CTRL + E to execute the command. The column index_name in the results pane of Query Analyzer will display the names of all indexes and statistics. 24 3. Use the name of the statistics in the drop statistics command. For example, to drop the statistic named _WA_Sys_VBELN_0AEA10A3, type the following commands in the Query window: drop statistics VBRP._WA_Sys_VBELN_0AEA10A3 4. Press CTRL + E to execute the commands. 5. Repeat Steps 1 through 4 for all statistics on the tables VBMOD, VBHDR, and VBDATA. DBCC SHOWCONTIG The DBCC SHOWCONTIG command is used to evaluate the level of physical fragmentation (if any) occurring on a table. Example of running DBCC SHOWCONTIG (Query Analyzer) 1. Type the following commands in the Query window: declare @id int select @id = object_id('saptest1') dbcc showcontig (@id) 2. Press CTRL + E to execute the commands. 3. The following output should result: DBCC SHOWCONTIG scanning 'saptest1' table... Table: 'saptest1' (933578364); index ID: 1, database ID: 5 TABLE level scan performed. - Pages Scanned................................: 4167 - Extents Scanned..............................: 521 - Extent Switches..............................: 520 - Avg. Pages per Extent........................: 8.0 - Scan Density [Best Count:Actual Count].......: 100.00% [521:521] - Logical Scan Fragmentation ..................: 11.21% - Extent Scan Fragmentation ...................: 0.96% - Avg. Bytes Free per Page.....................: 198.6 - Avg. Page Density (full).....................: 97.55% DBCC execution completed. If DBCC printed error messages, contact your system administrator. Scan Density and Extent Scan Fragmentation help assess how well organized a table is on disk. One hundred percent Scan Density is the best possible value because it indicates that optimal number of extents are in use (for example, each extent is fully utilized with eight pages per extent). Extent Scan Fragmentation provides additional information on page splitting by indicating if the extents associated with the table ever move physically out of sequence on disk. Extent Scan Fragmentation is usable information only when there is a clustered index defined on the table. 25 Avg. Page Density (full) indicates average amount of data on each SQL Server data page as a percentage. Sometimes, this percentage is also referred to as the fullness of the data page. A high percentage means that more data is brought into the SQL Server buffer cache with each 8 KB read. Overall, a high percentage means that the cache will contain more usable information. As an example, consider if the DBCC SHOWCONTIG indicated that there were several tables in your database that had an average page density of 50 percent. If these tables held a majority of the data that is retrieved, the SQL Server buffer cache will contain mostly data pages that only contains 50 percent of useful data. This would mean that a 1-GB buffer cache would contain only 500 MB of SQL Server data. If the average page density across tables being read into buffer cache were to improve to near 100 percent, a 1-GB buffer cache would contain close to 1 GB of SQL Server data, a much better situation. If response times for queries accessing a table grow to unacceptably high levels, run the DBCC SHOWCONTIG command on that table. If Avg. Pages per Extent is significantly less than 8.0, Extent Scan Fragmentation is greater than 10-20 percent or Avg. Page Density (full) is significantly lower than 100 percent, it is worthwhile to consider rebuilding the clustered index on the table in order to physically resequence the data in the table onto physically contiguous extents. Rebuilding the clustered index also provides to option of choosing a fuller page fill in order to compact more data per 8-KB page. Having well-compressed and contiguous data on disk helps I/O performance because SQL Server can make use of sequential I/O (which is much faster than nonsequential disk I/O) when fetching from this table and brings the maximum amount of usable SQL Server data into buffer cache with each read. FillFactor FillFactor is an option available with the CREATE INDEX statement which allows for control of the fullness of the leaf level of indexes. The leaf level of a table’s clustered index are the data pages of the table so use of the FillFactor option allows for control of the fullness of data pages on tables which use a clustered index. The default value for FillFactor is zero. This default value enforces 100 percent fill in all of the data pages of a table. Microsoft’s IT organization has been using the default value for FillFactor for a majority of the SQL Server tables in its SAP R/3 environment with excellent performance results. It is recommended that the default value for FillFactor be used as a starting point for R/3 database server testing. The key relationship to keep in mind with FillFactor is that the I/O performance benefit of having the maximum amount of data packed into each data and index page should be balanced against the performance benefit of avoiding page splits. Page splits occur when data needs to be inserted into a page but the page is full. A new page has to be used, and data is reorganized across the old and new page. The enhanced storage structures of SQL Server 7.0 make page split operations much more efficient than SQL Server 6.5; there is not as much of a performance penalty from page splits. That is the reason why the default FillFactor setting is a good place to start. If the DBCC SHOWCONTIG command reports that there is significant physical fragmentation occurring on a table and response times for the table are poor, the clustered index on that table should be rebuilt in order keep the index B-Tree structures in optimal form. The DROP_EXISTING option of the CREATE INDEX command is required in order to rebuild primary keys. It also provides enhanced performance for any index rebuild. The 26 examples below assume that the indexes from the original saptest1 table described earlier are being rebuilt. Example of rebuilding a clustered primary key (Query Analyzer) 1. Type the following command in the Query window: create unique clustered index sapt_c1 on saptest2(col1,col2,col3) with drop_existing 2. Press CTRL + E to execute the command. Example of rebuilding a nonclustered primary key (Query Analyzer) 1. Type the following command in the Query window: create unique index sapt_c1 on saptest2(col1,col2,col3) with drop_existing 2. Press CTRL + E to execute the command. Example of rebuilding a clustered index (Query Analyzer) 1. Type the following command in the Query window: create clustered index ckey1 on saptest2(col2) with drop_existing 2. Press CTRL + E to execute the command. There may be some R/3 environments where insert activity is very high and it will be worthwhile to test the use of a lower percentage fill on data and index pages so that page splitting will be minimized. For more information about the syntax for using FillFactor in the CREATE INDEX statement, see SQL Server Books Online. 27 File and Filegroup Design File Sizing and Use of AutoGrow It is recommended that SQL Server files be sized such that there will be at least three equally sized SQL Server files per RAID array and these files should be set at maximum size to which they are expected to grow. Use autogrow to cover sizing emergencies. Defining three files is helpful for speeding up data redistribution if it is determined that more I/O processing power is required and a new RAID array needs to be brought online. To move data to the new array, the ALTER DATABASE command can be used to modify the database such that one file is located on the new RAID array. Then SQL Server can be shut down, the file can be quickly moved to the new array, and SQL Server can be brought back up. Use the MAXSIZE option of the ALTER DATABASE command to prevent autogrow from exceeding the capacity of the RAID array. Prior to any file becoming full, use the ALTER DATABASE command to add a new file to the filegroup. Transaction Log Sizing For best performance, it is recommended that transaction logs be created at the largest size that they will be expected to reach versus using a small initial size and letting autogrow increase the size of the log. This helps keep number of virtual log files down. Use autogrow to cover emergency growth of the transaction log files. Use the MAXSIZE option of the ALTER DATABASE command, as illustrated below for tempdb to limit the growth of transaction log files so they do not exceed the capacity of the physical disk(s). tempdb Sizing It is recommended that tempdb be sized at a minimum of 250 MB. Autogrow should be enabled but if it is known through testing and previous experience that a large tempdb size will be required, it is recommended that tempdb be set to that size, versus letting autogrow expand tempdb to the required larger size, from the initial size of 250 MB. To limit autogrowth of tempdb to 4GB (Query Analyzer): 1. Type the following command in the Query window: Exec sp_helpdb tempdb 2. Press CTRL+E to execute the command. In the first column of the second section of the result set that the command returns, there will be the logical file names of the data and log files associated with tempdb. The logical file name for the tempdb data file will be used in the ALTER DATABASE command. In this case, the logical file name for the tempdb data file is tempdev. 3. Type the following command in the Query window: alter database tempdb modify file (name = tempdev, maxsize = 4000) 4. Press CTRL+E to execute the command. 28 Finding More information http://msdn.microsoft.com/developer/sqlserver/sql7perftune.htm is a link to the Microsoft SQL Server 7.0 Performance Tuning Guide that provides valuable information about creating SQL Server indexes, tuning disk I/O, RAID, and use of SQL Server 7.0 performance tools. SAP administrators working with SAP installations running SQL Server are strongly encouraged to review this document. SQL Server documentation provides information about SQL Server architecture and database tuning along with complete documentation of command syntax and administration. Install SQL Server Books Online on the hard disk drives of computers that use SQL Server regularly because it is an extremely useful reference. For the latest information about SQL Server, including other documents, visit the SQL Server Web site at www.microsoft.com/sql/. R/3 Installation on Windows NT – Microsoft SQL Server Database - SAP Release 4.0B – Document Product ID 51002828 - Available from SAP AG. Database Conversion: Microsoft SQL Server version 6.5 to 7.0 – Document Product ID 51003094 - Available from SAP AG. The MSDN™ Library compact disc provides a wealth of information about Microsoft technology. An example of the useful technical content that the MSDN Library compact disc provides which is particularly relevant to the performance tuning issues that are being discussed in this document would be the Windows NT Server 4.0 Resource Kit - Supplement 1, which provides some very helpful information about how to monitor Windows NT-based servers. For more information about obtaining a MSDN compact disc subscription, refer to http://msdn.microsoft.com/developer/join/subscriptions.htm. 29