Monitoring the Performance of Your SAP SQL Database Files

 

The driving force behind outstanding performance with SQL Server is a technique called Proportional Fill. This is how SQL Server writes to your file groups. When running SAP on SQL, only the PRIMARY file group can be used. The principal behind this technique is to write the data across all data files proportionally according to the amount of free space that is available for each file. Here are a few examples:

Example 1 – SQL needs to place data on three extents within your database

·        File1 has 100 MB free space

·        File2 has 100 MB free space

·        File3 has 100 MB free space

·        SQL Server will place one extent of data on all three files

Example 2 – SQL has 5 extents of data to be placed on the database

·        File1 has 50MB free space

·        File2 has 100MB free space

·        File3 has 100MB free space

·        1 extent on File1 and 2 extents each on File2 and File3 because twice the freespace is available.

Example 1 provides the optimal solution in spreading out data across all files equally. Example 2 is not optimal because you have more data going into file2 and file3 than file1. This can cause hot spots on the disk and unbalanced I/O which can lead to poor performance.

When all of your files are full, SQL Server will extend one file (in round robin fashion) to allow the database to grow. Autogrowth must be enabled to make this happen. This is also not what you want because it will cause your database to be disproportionately filled. If you files are getting close to being filled then you should manually extend all files by the same amount to maintain the proper proportional fill. With SQL Server 2008, this behavior can be modified by trace flag 1117. (See SAP Service Marketplace note 1238993) If trace flag 1117 is turned on, then when SQL Server goes to extend that first data file, it will extend all data files, preventing a possible problem with proportional fill. This trace flag is only valid for SQL Server 2008.

So, how do you determine if you have a problem? Well, there are a few ways that we will look at. You can get a good idea through SAP using transaction DBACOCKPIT.

Validate Data File Sizes

 Logon to SAP and then go to transaction DBACOCKPIT. You will the need to extend the SPACE folder and then select Overview. On the Display on the right side of the screen, select the FILES tab. See below.

As you can see from the screenshot #1 above, all of the files are sized at 15.755 MB and the free pct is almost identical at 9.00. NW7DATA1 is at 6.00. This is probably because it has just grabbed some additional space and the other data files will expand very soon too. NWLOG1 is the Tlogs and not a part of this discussion. The second screenshot above is the right side of the screen and shows that AUTOGROWTH is on with enough space to extend.

This is an example of what you want to see. All of the files are the same size with about the same amount of free space.

Next you want to look at your ms/read and ms/writes. If proportional fill is working correctly then the reads across the datafiles should almost be identical and the same should be true of the writes. You can find this in the DBACOCKPIT transaction too. Expand the PERFORMANCE folder on the left and then double click I/O Performance.

The above example is from a lab system and shows you what you don’t want to see. In the ms/Read column you can see the reads vary from 33,923 to 67,207. In the ms/Write column the numbers are closer, ranging from 11,625 to 16,222. Listed below is an export from a system that is running very well:

File

Partition

Type

Ms/Op

Ms/Read

Ms/Write

NW7_01

F:

Data

8.750

7.165

10.519

NW7_02

G:

 

8.856

7.296

10.424

NW7_03

H:

 

8.914

7.329

10.784

NW7_04

I:

 

8.955

7.362

10.848

NW7_05

J:

 

8.965

7.399

10.734

NW7_06

K:

 

8.964

7.405

10.628

NW7_07

L:

 

9.099

7.547

10.578

NW7_08

M:

 

9.128

7.575

10.831

NW7_log

T:

Log

2.104

9.055

1.740

 

Notice that the read and write times are very similar. This is exactly what you want to see.

That is two ways from within SAP that you can do a cursory check on your performance. If you would like to go a little deeper, there are a couple of SQL statements that can be executed to provide you with additional information. This information is covered in greater detail in a blog by Juergen Thomas called Proportional fill and how to check whether it works.

The first SQL statement will help you analyze your data files. It will look at the total number of reads and writes against all of your data files and then it will calculate the average number of reads/writes and compare that against the actual reads/writes. This will show you a percentage off each data file is from the average. Here is the SQL:

 

declare @avg_read bigint, @avg_write bigint

select @avg_read=avg(io.num_of_reads), @avg_write=avg(io.num_of_writes)

from sys.dm_io_virtual_file_stats(db_id(), -1) io, sys.database_files df

where io.file_id=df.file_id and df.type_desc = 'ROWS'

select io.file_id, df.name, io.num_of_reads, @avg_read as 'Avg Reads',

ceiling(((convert(decimal(10,0),num_of_reads)/@avg_read)*100)-100) as 'Percentage off Read Avg', io.num_of_writes, @avg_write as 'Avg Writes',

ceiling(((convert(decimal(10,2),num_of_writes)/@avg_write)*100)-100) as 'Percentage off Write Avg' from sys.dm_io_virtual_file_stats(db_id(), -1) io, sys.database_files df

where io.file_id=df.file_id and df.type_desc = 'ROWS'

 

You can execute this in SQL Management Studio. It will produce output that will look like the following:

File_Id

Name

Number of Reads

Avg Reads

Percentage off of Read Avg

Number of Writes

Avg Writes

Percentage off of Write Avg

1

NW7DATA1

52640796

43631430

21

2769624

3343182

-17

2

NW7DATA2

56839043

43631430

31

3251608

3343182

-2

3

NW7DATA3

57449320

43631430

32

3403255

3343182

2

4

NW7DATA4

59263332

43631430

36

3118588

3343182

-6

5

NW7DATA5

57061251

43631430

31

2911036

3343182

-12

6

NW7DATA6

58347537

43631430

34

2893586

3343182

-13

7

NW7DATA7

30797062

43631430

-29

4622042

3343182

39

8

NW7DATA8

30716323

43631430

-29

4616088

3343182

39

 

This is an example of a system that has some problems. In a system that is operating normally, you would expect the reads/writes to be very close in number and the percentages to be -2 to 2. This system had files that had been added, but the free space was not adjusted and proportional fill was out of sync.

The next check is a stored procedure that will analyze a table and see how it is allocated across your data files. Once again, you will execute this within SQL Server Management Studio. You will need to create the stored procedure and then execute it with the table you have selected. I would recommend that you use one of the largest tables in your database. You can easily determine this in DBACOCKPIT, expand the SPACE folder and double click Largest Tables.

Here is the stored procedure code:

drop procedure sp_tablepart

go

create procedure sp_tablepart @tname sysname as

begin

set nocount on

declare @extentinfo9p table (file_id int, page_id int, pg_alloc int, ext_size int,

      obj_id int, index_id int, partition_number int, partition_id bigint, iam_chain_type varchar(20), pfs_bytes varbinary(8))

declare @exec_statement varchar(512), @tname2 sysname, @dbid int, @fname sysname, @page_count bigint

set @dbid=db_id()

set @tname2 = quotename(@tname)

set @exec_statement = 'dbcc extentinfo(' + convert(varchar,@dbid) + ',' + @tname2 + ') with no_infomsgs'

insert into @extentinfo9p exec (@exec_statement)

select @page_count = SUM(pg_alloc) from @extentinfo9p

select distinct (ei.file_id) as 'File ID', df.name as 'Name',

fg.name as 'Filegroup Name', SUM(ei.pg_alloc) as 'Pages allocated',

ROUND(((convert(decimal,SUM(ei.pg_alloc))/convert(decimal,@page_count))*100),1) as Percentage

from @extentinfo9p ei, sys.database_files df, sys.filegroups fg

where ei.file_id = df.file_id and df.data_space_id=fg.data_space_id

group by ei.file_id, df.name, fg.name order by ei.file_id

end

 

To execute the stored procedure enter this command:

sp_tablepart ‘schema.tablename’

Example: sp_tablepart ‘nw7.BSIS’

You will receive output similar this:

File ID

Name

Filegroup Name

Pages allocated

Percentage

1

Data1

PRIMARY

16928

3

3

Data2

PRIMARY

17327

3

4

Data3

PRIMARY

17154

3

5

Data4

PRIMARY

17430

3.1

6

Data5

PRIMARY

18418

3.2

7

Data6

PRIMARY

17703

3.1

8

Data7

PRIMARY

18808

3.3

30

Data29

PRIMARY

17825

3.1

31

Data30

PRIMARY

17751

3.1

32

Data31

PRIMARY

17852

3.1

33

Data32

PRIMARY

17545

3.1

 

This is an example of a table that has been proportionally distributed across all data files and is exactly what you are looking for.

Correcting Proportional Fill Issues

The best way to correct any problems you might be experiencing is by performing a homogeneous system copy. You will find guides on the SAP Service Marketplace to help you with this. Once you have exported your database, you would then re-create your data files ensuring that they are all the same size. Once you perform the import, your data should be proportionally distributed. This is a very time consuming process and many of your will not have the luxury of getting this much down time.

Another alternative is to re-size your existing data files. Make sure that each and every file has the same amount of freespace. This will cause SQL Server to begin to proportionally fill the data files again. It will not correct what has already been done.

All in all, if you setup and maintain your data files correctly, this should not be an issue. If you are running SQL Server 2008 and higher, set trace flag 1117. I hope this blog will help you in maintaining excellent performance on your system.