简体   繁体   中英

SQL Server Plans : difference between Index Scan / Index Seek

In a SQL Server Execution plan what is the difference between an Index Scan and an Index Seek

I'm on SQL Server 2005.

An index scan is where SQL server reads the whole of the index looking for matches - the time this takes is proportional to the size of the index.

An index seek is where SQL server uses the b-tree structure of the index to seek directly to matching records (see http://mattfleming.com/node/192 for an idea on how this works) - time taken is only proportional to the number of matching records.

  • In general an index seek is preferable to an index scan (when the number of matching records is proprtionally much lower than the total number of records), as the time taken to perform an index seek is constant regardless of the toal number of records in your table.
  • Note however that in certain situations an index scan can be faster than an index seek (sometimes significantly faster) - usually when the table is very small, or when a large percentage of the records match the predicate.

The basic rule to follow is Scans are bad, Seeks are good.

Index Scan

When SQL Server does a scan it loads the object which it wants to read from disk into memory, then reads through that object from top to bottom looking for the records that it needs.

Index Seek

When SQL Server does a seek it knows where in the index that the data is going to be, so it loads up the index from disk, goes directly to the part of the index that it needs and reads to where the data that it needs ends. This is obviously a much more efficient operation than a scan, as SQL already knows where the data it is looking for is located.


How can I modify an Execution Plan to use a Seek instead of a Scan?

When SQL Server is looking for your data probably one of the largest things which will make SQL Server switch from a seek to a scan is when some of the columns are you looking for are not included in the index you want it to use. Most often this will have SQL Server fall back to doing a clustered index scan, since the Clustered index contains all the columns in the table. This is one of the biggest reasons (in my opinion at least) that we now have the ability to INCLUDE columns in an index, without adding those columns to the indexed columns of the index. By including the additional columns in the index we increase the size of the index, but we allow SQL Server to read the index, without having togo back to the clustered index, or to the table it self to get these values.

References

For information regarding the specifics of each of these operators within a SQL Server Execution plan see....

Scans vs. Seeks


Index Scan:

Since a scan touches every row in the table, whether or not it qualifies, the cost is proportional to the total number of rows in the table. Thus, a scan is an efficient strategy if the table is small or if most of the rows qualify for the predicate.

Index Seek:

Since a seek only touches rows that qualify and pages that contain these qualifying rows, the cost is proportional to the number of qualifying rows and pages rather than to the total number of rows in the table.

Index Scan is nothing but scanning on the data pages from the first page to the last page. If there is an index on a table, and if the query is touching a larger amount of data, which means the query is retrieving more than 50 percent or 90 percent of the data, and then the optimizer would just scan all the data pages to retrieve the data rows. If there is no index, then you might see a Table Scan (Index Scan) in the execution plan.

Index seeks are generally preferred for the highly selective queries. What that means is that the query is just requesting a fewer number of rows or just retrieving the other 10 (some documents says 15 percent) of the rows of the table.

In general query optimizer tries to use an Index Seek which means that the optimizer has found a useful index to retrieve record set. But if it is not able to do so either because there is no index or no useful indexes on the table, then SQL Server has to scan all the records that satisfy the query condition.

Difference between a scan and a seek?

A scan returns the entire table or index. A seek efficiently returns rows from one or more ranges of an index based on a predicate. For example, consider the following query:

select OrderDate from Orders where OrderKey = 2

Scan

With a scan, we read each row in the orders table, evaluate the predicate “where OrderKey = 2” and, if the predicate is true (ie, if the row qualifies), return the row. In this case, we refer to the predicate as a “residual” predicate. To maximize performance, whenever possible we evaluate the residual predicate in the scan. However, if the predicate is too expensive, we may evaluate it in a separate filter iterator. The residual predicate appears in text showplan with the WHERE keyword or in XML showplan with the tag.

Here is the text showplan (slightly edited for brevity) for this query using a scan:

|–Table Scan(OBJECT:([ORDERS]), WHERE:([ORDERKEY]=(2)))

The following figure illustrates the scan:

在此输入图像描述

Since a scan touches every row in the table whether or not it qualifies, the cost is proportional to the total number of rows in the table. Thus, a scan is an efficient strategy if the table is small or if most of the rows qualify for the predicate. However, if the table is large and if most of the rows do not qualify, we touch many more pages and rows and perform many more I/Os than is necessary.

Seek

Going back to the example, if we have an index on OrderKey, a seek may be a better plan. With a seek, we use the index to navigate directly to those rows that satisfy the predicate. In this case, we refer to the predicate as a “seek” predicate. In most cases, we do not need to re-evaluate the seek predicate as a residual predicate; the index ensures that the seek only returns rows that qualify. The seek predicate appears in the text showplan with the SEEK keyword or in XML showplan with the tag.

Here is the text showplan for the same query using a seek:

|–Index Seek(OBJECT:([ORDERS].[OKEY_IDX]), SEEK:([ORDERKEY]=(2)) ORDERED FORWARD)

The following figure illustrates the seek:

在此输入图像描述

Since a seek only touches rows that qualify and pages that contain these qualifying rows, the cost is proportional to the number of qualifying rows and pages rather than to the total number of rows in the table. Thus, a seek is generally a more efficient strategy if we have a highly selective seek predicate; that is, if we have a seek predicate that eliminates a large fraction of the table.

A note about showplan

In showplan, we distinguish between scans and seeks as well as between scans on heaps (an object with no index), clustered indexes, and non-clustered indexes. The following table shows all of the valid combinations:

在此输入图像描述

https://blogs.msdn.microsoft.com/craigfr/tag/scans-and-seeks/

Short answer:

  • Index scan: Touch all rows but certain columns.

  • Index seek: Touch certain rows and certain columns.

With an Index Scan, all rows in the index are being scanned to find a matching row. This can be efficient for small tables. With an Index Seek, it only needs to touch the rows that actually meet the criteria and so is generally more performant

An Index Scan happens when the index definition cannot find on a single row to satisfy search predicates. In this case SQL Server has to scan multiple pages to find a range of rows which satisfy the search predicates.

In the case of a Index Seek, SQL Server finds a single row matching search predicates using index definition.

Index Seeks are better and more effective.

A scan touches every row in the table even if its what you are after or not

A seek looks only at the rows that are what you are looking for.

Seeks are always better to have than scans as they are more efficient in the way it looks data up.

A good explanation can be found here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM