Summary Description

The SQL language is spoken by most database experts, and all relational database products include some dialect of the SQL standard. Nevertheless, each product has its own particular query-processing mechanism. Understanding the way a database engine processes queries helps software architects, designers, and programmers make good choices when designing database schemas and writing queries.

When a query reaches the database engine, the SQL Server performs two major steps to produce the desired query result. The first step is query compilation, which generates a query plan, and the second step is the execution of the query plan.

Query compilation in SQL Server 2005 consists of three steps: parsing, algebrization, and query optimization. After those steps are completed, the compiler stores the optimized query plan in the procedure cache. There, the execution engine copies the plan into its executable form and subsequently executes the steps in the query plan to produce the query result. If the same query or stored procedure is executed again and the plan is located in the procedure cache, the compilation step is skipped and the query or stored procedure proceeds directly to execution reusing the stored plan.

Commands Generating Various Formats of a Showplan









Operators and estimated costs



Display Estimated Execution Plan in Management Studio

Run-time info



Include Actual Execution Plan in Management Studio

Showplan-Related Trace Event Classes

Trace Event Class

Compile or Run

Includes run-time info

Includes XML showplan

Generates trace against SQL Server 2000

Showplan All





Showplan All for Query Compile





Showplan Statistics Profile





Showplan Text





Showplan Text (Unencoded)





Showplan XML





Showplan XML for Query Compile





Showplan XML Statistics Profile





Performance Statistics

Compile and Run[4]




Update Plans

The query optimizer must take care of several specific issues when optimizing INSERT, UPDATE, and DELETEor, in other words, data modifyingstatements. Here I will describe the techniques employed by the SQL Server to process these statements.

The IUD (shorthand I will use for "INSERT, UPDATE, and DELETE") plans have two stages. The first stage is read only, and it determines which rows need to be inserted/updated/deleted by generating a data stream describing the changes to be made. For INSERTs, the data stream contains column values; for DELETEs, it has the table keys; and for UPDATEs, it has both the table keys and the values of changed columns. The second stage applies changes in the data stream to the table; additionally, it takes actions necessary to preserve data integrity by performing constraint validation, it maintains nonclustered indexes and indexed views, and it fires triggers if they exist. Usually the UPDATE and DELETE query plans contain two references to the target table: the first reference is used to identify the affected rows and the second to perform the change. The INSERT plans contain only one reference to the target table unless the same target table also participates in generating the inserted rows.

In some simple cases, SQL Server merges the read and write stages of the IUD plans together. This is the case, for example, when inserting values directly into a table (a process known as a scalar insert) or updating/deleting rows identified by a value of a primary key on the target table.

The Assert operator is automatically included in the query plans in the second phase if SQL Server needs to perform constraint validation. SQL Server validates the CHECK constraints for INSERTs and UPDATEs by evaluating a usually inexpensive scalar expression on each affected row and column. Foreign key constraints are enforced on INSERTs and UPDATEs to the table containing the foreign key constraint, and they're enforced on UPDATEs and DELETEs to the table containing the referenced key. The related table that is not the target of the IUD operation is scanned to verify the constraint; therefore, data access is involved. Declaring a primary key automatically creates a unique index on the key columns, but this is not the case for a foreign key. UPDATEs and DELETEs of referenced keys must access the foreign key table for each updated or deleted primary key value, either to validate nonexistence of the removed key or to propagate the change if it is a cascading referential integrity constraint. Therefore, you should ensure there is an index on the foreign key if you plan to perform UPDATEs affecting the key values or DELETEs from the primary table.

In addition to performing the IUD operation on the clustered index or heap, processing of the INSERT and DELETE queries also maintains all nonclustered indexes, and the UPDATE queries maintain indexes containing the modified columns. Because nonclustered indexes include the clustered index and partitioning keys to allow efficient access to the table row, updating columns that participate in the clustered index or in the partitioning key is expensive because it requires maintenance of all indexes. Updating the partitioning key might also cause rows to move between partitions. Therefore, when you have a choice, choose clustering and partitioning keys that you don't plan to update.



SQL Server 2005 restricts the partitioning keys to a single column; therefore, "partitioning key" and "partitioning column" are synonyms.

In general, the performance of IUD statements is closely tied to the number of maintained indexes that include the target columns, because those must all be modified. Performing single-row INSERT and DELETE operations to an index requires a single index-tree traversal. SQL Server implements update to an index or partitioning key as a DELETE followed by an INSERT therefore, it is roughly twice as expensive as a nonkey UPDATE.


You can use DBCC FREEPROCCACHE to clear up the procedure cache to ensure the compilation will take place afterwards. However, you should be careful using the DBCC FREEPROCCACHE on production servers because it will delete the contents of the procedure cache, and all statements and stored procedures will have to be compiled anew

The DOP is 0 (which means serial plan), which shows the actual degree of parallelism (or DOP, which is the number of concurrent threads working on the single query) of the execution

Observe that in the preceding example I used SET SHOWPLAN_TEXT OFF following the query. This is because SET SHOWPLAN_TEXT ON is not only causing the query plan to show up, it is also turning off query execution for the connection. Query execution will stay turned off until SQL Server executes SET SHOWPLAN_TEXT OFF on the same connection

When examining the plan for a particular query, a good way to find potential problems is to find the biggest discrepancies between the optimizer's estimates and the real number of executes and returned rows. Here we must be careful because the optimizer's estimate in the column EstimateRows is per estimated execution, while the Rows in the showplan output mentioned previously is the cumulative number of rows returned by the operator from all its executions. Therefore, to assess the optimizer's discrepancy we must multiply the EstimateRows by EstimateExecutions and compare the result with the actual number of all rows returned in the Rows column of the SET STATISTICS PROFILE output.

After the query optimizer produces the plan for the batch or stored procedure, the plan is placed in the procedure cache. You can examine the procedure cache using several dynamic management views (DMV) and functions (DMF), DBCC PROCCACHE, and the deprecated catalog view sys.syscacheobjects. I will show how you can access a showplan in XML format for the queries currently in the procedure cache.

Inside TSQL Querying - Chapter 2. Physical Query Processing的更多相关文章

  1. Inside TSQL Querying - Chapter 1. Logical Query Processing

    Logical Query Processing Phases Summary (8) SELECT (9) DISTINCT (11) <TOP_specification> <s ...

  2. Inside TSQL Querying - Chapter 3. Query Tuning

    Tuning Methodology When dealing with performance problems, database professionals tend to focus on t ...

  3. Inside Microsoft SQL Server 2008: T-SQL Querying 读书笔记之查询优化

    一. 自顶向下优化方法论 1. 分析实例级别的等待 在实例级找出什么类型的等待占用大部分的时间,通过sys.dm_os_wait_stats select wait_type, --等待类型 wait ...

  4. Inside Microsoft SQL Server 2008: T-SQL Querying 读书笔记1

    (5)SELECT   (5-2) DISTINCT    (5-3)TOP(<top_specifications>)   (5-1)<select_list> (1)FRO ...

  5. 动态Pivot(1)

    原文 7.7  动态Pivot 作为另外一个练习,假设你要编写一个存储过程,它生成动态Pivot查询.这个存储过程 ...

  6. Spring SimpleJdbcTemplate Querying examples

    Here are few examples to show how to use SimpleJdbcTemplate query() methods to query or extract data ...

  7. T-SQL XQuery (XML路径查询) (转)

    /* T-SQL 支持用于查询 XML 数据类型的 XQuery 语言的子集. XQuery 基于现有的 XPath 查询语言,并支持更好的迭代.更好的排序结果以及构造必需的 XML 的功能. 在前面 ...

  8. 转载---SQL Server XML基础学习之&lt;5&gt;--XQuery(query)

    本章写一些SQL Server XML的一些XQuery基础语法,主要讲的query查询语法 T-SQL 支持用于查询 XML 数据类型的 XQuery 语言的子集. XQuery 基于现有的 XPa ...

  9. NoSQL数据库笔谈(转)

    NoSQL数据库笔谈 databases , appdir , node , paper颜开 , v0.2 , 2010.2 序 思想篇 CAP 最终一致性 变体 BASE 其他 I/O的五分钟法则 ...


  1. 初探java中this的用法

    一般this在各类语言中都表示“调用当前函数的对象”,java中也存在这种用法: public class Leaf { int i = 0; Leaf increment(){ i++; retur ...

  2. 《Android深度探索HAL与驱动开发》第四章阅读心得

     Android源代码包含了很多内容,可以实现拍照.计算机.日历.相册.拨号器等功能.配置Android源代码下载环境需要如下几步: (1)创建一个用于存放下载脚本文件的目录:  (2)下载repo脚 ...

  3. Netty_Netty系列之Netty百万级推送服务设计要点

    1. 背景 1.1. 话题来源 最近很多从事移动互联网和物联网开发的同学给我发邮件或者微博私信我,咨询推送服务相关的问题.问题五花八门,在帮助大家答疑解惑的过程中,我也对问题进行了总结,大概可以归纳为 ...

  4. [python] import curses

    python 中,我们使用 curses.wrapper 来创建终端交互window.使用 stdscr 来代表 window 对象. 使用方法: from curses import wrapper ...

  5. jxl 2.6.12 与 jxl 2.3.0 稳定版性能比较

    jxl 2.3.0 org.jxls:jxls:2.3.0 org.jxls:jxls-poi:1.0.9 org.jxls:jxls-jexcel:1.0.6 jxls-reader:2.0.2 j ...

  6. mysql批量生成修改表和列注释语句

    当我们在一个数据库修改完备注后,需要将其导致另一个服务器上的数据库中,需要生成批量执行语句,方便操作,注意用change 或modified 进行列的属性修改时,没有写全的话会造成其它属性的丢失,如 ...

  7. HTML5和css3的总结三

    继续总结H5的新东西 1>序列化与反序列化 序列化:其实就是一个json->string的过程 JSON.stringify(json); 反序列化:string->json的过程( ...

  8. String类常用方法。

    一,字符数组与字符串. 一个字符串可以变成一个字符数组,同样,一个字符数组可以变成一个字符串. 在String类中提供了以下操作方法. 1)将字符串变成字符数组:public char[] toCha ...

  9. iOS开发小技巧--初始化项目中修改APP安装后的名称

  10. Android中this.*与*.this还有*.class的区别是什么?

    这些是java的基础知识.首先this代表本类的一个引用,this.*表示调用本类的某个方法,这个时候通常可以省略this:但在内部类中不能省略,否则编译器会认为是内部类的引用,所以要在this前加上 ...