未加星标

SQL Server Read Ahead Reads Example

字体大小 | |
[数据库(mssql) 所属分类 数据库(mssql) | 发布者 店小二03 | 时间 2017 | 作者 红领巾 ] 0人收藏点击收藏

By:Neeraj Prasad Sharma || Related Tips:More >Performance Tuning

Problem

SQL Server has many features that assist with providing the best query performance and one of these features is read ahead reads or prefetching. In this tip we look at how this relates to SQL Server query performance and if there is an impact to query performance.

Solution

SQL Server tries to respond to a user's query as quickly as possible. To achieve this, SQL Server tries hard at multiple levels of operation to make the query plan efficient. However, most of the performance related work done by the query optimizer is to get the best access method of the data, like what join is best, which physical join type is appropriate, should it scan or seek the index, etc. Even if the query optimizer comes up with the best execution method, the query can still suffer because there could be a considerable CPU or I/O performance gap, to reduce some of this SQL Server uses the read ahead read mechanism.

The read ahead mechanism is SQL Servers ability to bring data pages into the buffer cache even before the data is requested by the relational engine. Whenever the relational engine asks for rows from the storage engine, it first looks for those pages that contain the rows in the buffer cache. If not found, it then copies those pages from physical storage to the buffer cache. The storage engine can anticipate that more pages might be required by the relational engine and it initiates the read ahead read mechanism. There are two read ahead read mechanisms; sequential read ahead reads and random prefetching.

A sequential read ahead read tries to read pages in a specific order either in allocation order or index order. Heaps are always scanned in the allocation order as heaps don't store data in any specified order. Indexes scan in the key order on which they are sorted, unless it's running on the read uncommitted isolation level or the nolock hint is used and the relation engine doesn't ask for an ordered scan. SQL Server supports random IOs as well. On a conventional rotating disk, random IOs are much slower than sequential IOs, thus for better performance throughput it has to support read ahead reads, which is called random prefetching.

Usually random IOs are generated by a nested loop join physical join type. In a nested loop join the outer table generates random IOs to the inner table for the matching rowset. In a nested loop join prefetching is only enabled if the outer table's estimated number of rows is more than 25. Random prefetching can be further categorized as ordered and unordered prefetching.

Let's try to understand RAR (Read Ahead Read) with examples, that we will build a test table with some random data. To view the read ahead read phenomena we will enable statistics IO when we run the queries. Also, I will run DBCC DROPCLEANBUFFERS to flush all the data pages before each run, so the read ahead reads take place.

Note: DBCC DROPCLEANBUFFERS is not recommended on production servers, unless there is an absolute need. Running this command flushes the buffer cache.

Build Test Data CREATE TABLE DBO.TestTable (
ID int IDENTITY (1, 1) NOT NULL,
IDvarchar AS CAST(ID AS varchar(50)) PERSISTED NOT NULL,
intcolumn int,
NAME varchar(50) NOT NULL,
Age int NOT NULL,
Randomvalue bigint
);
INSERT INTO TestTable (intcolumn, NAME, AGE)
SELECT s1.number, 'Some Random Data..', s1.number % 10 + 25
FROM master.dbo.spt_values s1
CROSS JOIN master.dbo.spt_values s2;
UPDATE TestTable
SET Randomvalue = CAST(RAND(CHECKSUM(NEWID())) * ID AS int);
ALTER TABLE TestTable ALTER COLUMN Randomvalue int NOT NULL;
CREATE UNIQUE CLUSTERED INDEX CI_TestTable_ID ON DBO.TestTable (ID) SQL Server Read Ahead Read Example

Now that the test data has been built, we can start the test.

In the below query, we will first clean the buffer cache by using DBCC DROPCLEANBUFFERS , so there will be nothing in the buffer cache and the reads will be physical reads, so read ahead reads can take place.

To check whether the read ahead read mechanism occurred, we will can check the output of statistics io . Look at the read-ahead reads information below, we can see that 2 read-ahead read pages were brought into the buffer pool.

DBCC DROPCLEANBUFFERS;SET STATISTICS IO ON;
SELECT * FROM TestTable WHERE ID <300;
--Table 'TestTable'. Scan count 1, logical reads 5, physical reads 1, read-ahead reads 2, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Now run the same query again without clearing the buffer cache. There is no need for read ahead reads, because those pages are already in the buffer pool.

SET STATISTICS IO ON;SELECT * FROM TestTable WHERE ID <300;
--Table 'TestTable'. Scan count 1, logical reads 5, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Now run another query with a different value. The query is asking for different data pages which are not in the buffer cache already, so the RAR mechanism started and placed those pages into the buffer pool.

SELECT * FROM TestTable WHERE ID <600;
--Table 'TestTable'. Scan count 1, logical reads 7, physical reads 0, read-ahead reads 2, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0 SQL Server Random Prefetching Example

Now we will try to understand random prefetching with some examples. For this we need to build another table with some random data. Random prefetching can be experienced with a nested loop join, thus I will force the optimizer to choose a nested loop join so if you are testing this you will get the same physical join type.

SELECT * INTO Testtable2 FROM TestTable t1;CREATE unique clustered INDEX ix_id_testtable2 ON testtable2 (IDvarchar);
CREATE unique INDEX ix_IDVARCHAR ON testtable2 (IDvarchar);
DBCC DROPCLEANBUFFERS;
SET STATISTICS IO ON;
SELECT *
FROM TestTable t1
WHERE IDvarchar IN
(SELECT IDvarchar
FROM testtable2 t2)
AND ID < 27
OPTION (loop join);
--Table 'Testtable2'. Scan count 0, logical reads 143, physical reads 1, read-ahead reads 240, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
--Table 'TestTable'. Scan count 1, logical reads 3, physical reads 2, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

The statistics io shows there is no read-ahead reads on the TestTable, but there are on TestTable2.

In the execution plan, the outer table, TestTable, estimated rows is 26 thus the random prefetching is enabled for the inner table TestTable2. Prefetching can be confirmed by right clicking on the Nested Loops Inner Join and selecting Properties. In the properties there is a property named WithUnorderedPrefetch which is equal to TRUE.


SQL Server Read Ahead Reads Example

A quick test to see when random prefetching is not enabled is to use a row count less than 26.

DBCC DROPCLEANBUFFERS;
SET STATISTICS IO ON;
SELECT *
FROM TestTable t1
WHERE IDvarchar IN
(SELECT IDvarchar
FROM testtable2 t2)
AND ID < 26
OPTION (loop join);
--Table 'Testtable2'. Scan count 0, logical reads 75, physical reads 30, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
--Table 'TestTable'. Scan count 1, logical rea

本文数据库(mssql)相关术语:熊片数据库 mssql数据库 oracle数据库 pubmed数据库 access数据库 万方数据库

主题: SQLSQL ServerTICPUUFKSUOPTSU
分页:12
转载请注明
本文标题:SQL Server Read Ahead Reads Example
本站链接:http://www.codesec.net/view/520053.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 数据库(mssql) | 评论(0) | 阅读(67)