惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Jina AI
Jina AI
Forbes - Security
Forbes - Security
雷峰网
雷峰网
人人都是产品经理
人人都是产品经理
博客园 - 叶小钗
V
Visual Studio Blog
月光博客
月光博客
博客园 - Franky
有赞技术团队
有赞技术团队
宝玉的分享
宝玉的分享
博客园 - 三生石上(FineUI控件)
酷 壳 – CoolShell
酷 壳 – CoolShell
Apple Machine Learning Research
Apple Machine Learning Research
The Register - Security
The Register - Security
S
SegmentFault 最新的问题
博客园 - 司徒正美
P
Proofpoint News Feed
Know Your Adversary
Know Your Adversary
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
A
Arctic Wolf
Cyberwarzone
Cyberwarzone
Simon Willison's Weblog
Simon Willison's Weblog
U
Unit 42
P
Proofpoint News Feed
Scott Helme
Scott Helme
MyScale Blog
MyScale Blog
T
Tenable Blog
Hugging Face - Blog
Hugging Face - Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
小众软件
小众软件
C
CERT Recently Published Vulnerability Notes
P
Palo Alto Networks Blog
V
V2EX
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Tailwind CSS Blog
V
Vulnerabilities – Threatpost
Latest news
Latest news
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
I
Intezer
Microsoft Azure Blog
Microsoft Azure Blog
爱范儿
爱范儿
博客园 - 【当耐特】
B
Blog RSS Feed
N
Netflix TechBlog - Medium
Recent Announcements
Recent Announcements
NISL@THU
NISL@THU
C
Cisco Blogs
C
CXSECURITY Database RSS Feed - CXSecurity.com
S
Schneier on Security

博客园 - nzperfect

PAGELATCH_EX Contention on 2:1:103 SQL Server AlwaysON 同步模式的疑似陷阱 XEvent – SQL Server Log文件对磁盘的写操作大小是多少 SQL Server Log文件对磁盘的写操作大小是多少 Initializing the FallBack certificate failed . TDSSNIClient initialization failed Error after SQL Server 2012 installation: Login Failure for "SQL Server Integration Services 11.0" SSIS service SQL Server 灾难恢复31天之第6天:管理区分配页损坏处理 SQL Server 灾难恢复31天之第5天:处理损坏的非聚集索引 SQL Server 灾难恢复31天之第3天:在还原数据库时确定需要哪些备份文件 SQL Server 灾难恢复31天之第4天:备份 SQL Server 灾难恢复31天之第2天:包含数据库备份在还原时的保护 SQL Server 灾难恢复31天之第1天:DBCC CHECK命令会自动使用已经存在的数据库快照吗? 发布订阅延迟故障排查案例:分发读进程延迟 SQL Server 通过界面生成修改列类型脚本时的一个风险(或Bug) 是什么引起执行计划变得极其糟糕? 应该使用更新统计信息来解决它吗? 如何完整的修改一个数据库的名称 update值与原值相同时,SQL Server会真的去update还是忽略呢? How can I bring mirror database online after principal server is down ? performance monitor没有SQL Server性能计数器
Query Hint FAST number_rows 改变SQL Server 执行计划
nzperfect · 2012-12-28 · via 博客园 - nzperfect

作者:nzperfect
本文地址:http://www.cnblogs.com/nzperfect/archive/2012/12/28/2837286.html

本文示例使用FASH nuber_rows改变SQL执行计划
准备测试数据:

USE TEMPDB
GO
--
建立基本数据: --/////////////////// CREATE TABLE STUDENT (SNO VARCHAR(3) NOT NULL, SNAME VARCHAR(4) NOT NULL, SSEX VARCHAR(2) NOT NULL, SBIRTHDAY DATETIME, CLASS VARCHAR(5)) GO CREATE TABLE COURSE (CNO VARCHAR(5) NOT NULL, CNAME VARCHAR(10) NOT NULL, TNO VARCHAR(10) NOT NULL) GO CREATE TABLE SCORE (SNO VARCHAR(3) NOT NULL, CNO VARCHAR(5) NOT NULL, DEGREE NUMERIC(10, 1) NOT NULL) GO CREATE TABLE TEACHER (TNO VARCHAR(3) NOT NULL, TNAME VARCHAR(4) NOT NULL, TSEX VARCHAR(2) NOT NULL, TBIRTHDAY DATETIME NOT NULL, PROF VARCHAR(6), DEPART VARCHAR(10) NOT NULL) INSERT INTO STUDENT (SNO,SNAME,SSEX,SBIRTHDAY,CLASS) VALUES (108 ,'曾华' ,'' ,1977-09-01,95033); INSERT INTO STUDENT (SNO,SNAME,SSEX,SBIRTHDAY,CLASS) VALUES (105 ,'匡明' ,'' ,1975-10-02,95031); INSERT INTO STUDENT (SNO,SNAME,SSEX,SBIRTHDAY,CLASS) VALUES (107 ,'王丽' ,'' ,1976-01-23,95033); INSERT INTO STUDENT (SNO,SNAME,SSEX,SBIRTHDAY,CLASS) VALUES (101 ,'李军' ,'' ,1976-02-20,95033); INSERT INTO STUDENT (SNO,SNAME,SSEX,SBIRTHDAY,CLASS) VALUES (109 ,'王芳' ,'' ,1975-02-10,95031); INSERT INTO STUDENT (SNO,SNAME,SSEX,SBIRTHDAY,CLASS) VALUES (103 ,'陆君' ,'' ,1974-06-03,95031); GO INSERT INTO COURSE(CNO,CNAME,TNO)VALUES ('3-105' ,'计算机导论',825); INSERT INTO COURSE(CNO,CNAME,TNO)VALUES ('3-245' ,'操作系统' ,804); INSERT INTO COURSE(CNO,CNAME,TNO)VALUES ('6-166' ,'数据电路' ,856); INSERT INTO COURSE(CNO,CNAME,TNO)VALUES ('9-888' ,'高等数学' ,100); GO INSERT INTO SCORE(SNO,CNO,DEGREE)VALUES (103,'3-245',86); INSERT INTO SCORE(SNO,CNO,DEGREE)VALUES (105,'3-245',75); INSERT INTO SCORE(SNO,CNO,DEGREE)VALUES (109,'3-245',68); INSERT INTO SCORE(SNO,CNO,DEGREE)VALUES (103,'3-105',92); INSERT INTO SCORE(SNO,CNO,DEGREE)VALUES (105,'3-105',88); INSERT INTO SCORE(SNO,CNO,DEGREE)VALUES (109,'3-105',76); INSERT INTO SCORE(SNO,CNO,DEGREE)VALUES (101,'3-105',64); INSERT INTO SCORE(SNO,CNO,DEGREE)VALUES (107,'3-105',91); INSERT INTO SCORE(SNO,CNO,DEGREE)VALUES (108,'3-105',78); INSERT INTO SCORE(SNO,CNO,DEGREE)VALUES (101,'6-166',85); INSERT INTO SCORE(SNO,CNO,DEGREE)VALUES (107,'6-106',79); INSERT INTO SCORE(SNO,CNO,DEGREE)VALUES (108,'6-166',81); GO INSERT INTO TEACHER(TNO,TNAME,TSEX,TBIRTHDAY,PROF,DEPART) VALUES (804,'李诚','','1958-12-02','副教授','计算机系'); INSERT INTO TEACHER(TNO,TNAME,TSEX,TBIRTHDAY,PROF,DEPART) VALUES (856,'张旭','','1969-03-12','讲师', '电子工程系'); INSERT INTO TEACHER(TNO,TNAME,TSEX,TBIRTHDAY,PROF,DEPART)VALUES (825, '王萍','','1972-05-05','助教', '计算机系'); INSERT INTO TEACHER(TNO,TNAME,TSEX,TBIRTHDAY,PROF,DEPART) VALUES (831,'刘冰','','1977-08-14','助教', '电子工程系');

加索引:

CREATE UNIQUE CLUSTERED INDEX IX_1 ON COURSE(CNO)
CREATE NONCLUSTERED INDEX IX_2 ON COURSE(TNO,CNO)

CREATE UNIQUE CLUSTERED INDEX IX_1 ON SCORE(SNO,CNO)
CREATE NONCLUSTERED INDEX IX_2 ON SCORE(CNO)


CREATE UNIQUE CLUSTERED INDEX IX_1 ON TEACHER(TNO)
CREATE NONCLUSTERED INDEX IX_2 ON TEACHER(TNAME,TNO)

查询语句写法一:

SELECT SC.*
FROM TEACHER TEA 
INNER JOIN COURSE CO ON TEA.TNO=CO.TNO 
INNER JOIN SCORE SC ON CO.CNO = SC.CNO
WHERE TEA.TNAME='张旭'

 查询语句写法二:

SELECT *
FROM SCORE SC
WHERE CNO IN ( 
    SELECT CNO
    FROM TEACHER TEA INNER JOIN COURSE CO
    ON TEA.TNO = CO.TNO
    WHERE TEA.TNAME='张旭'
) 

首先看下IO:

查询语句写法一:

Table 'SCORE'. Scan count 1, logical reads 6, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'COURSE'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'TEACHER'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
查询语句写法二:

Table 'TEACHER'. Scan count 0, logical reads 22, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'COURSE'. Scan count 0, logical reads 24, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'SCORE'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

从上面的IO可以看到写法二IO比写法一多一些逻辑读。

再比较一下执行计划:

写法一:

写法二:

上面这个写法二生成的执行计划看似不是我们想要的,我们的写法是:

SELECT *
FROM SCORE SC
WHERE CNO IN ( 
    SELECT CNO
    FROM TEACHER TEA INNER JOIN COURSE CO
    ON TEA.TNO = CO.TNO
    WHERE TEA.TNAME='张旭'
) 

按一般我们是这么想的:

step 1 : 先执行:

    SELECT CNO
    FROM TEACHER TEA INNER JOIN COURSE CO
    ON TEA.TNO = CO.TNO
    WHERE TEA.TNAME='张旭'

step 2 : 然后再执行:

SELECT *
FROM SCORE SC
WHERE CNO IN
(
    STEP 1 CNO结果
)

但实际上,但SQL执行计划并未按我们想的生成我们想要的执行计划,所以我打算想办法改变它,使用一个query hint : FAST number_rows

SELECT *
FROM SCORE SC
WHERE CNO IN ( 
    SELECT CNO
    FROM TEACHER TEA INNER JOIN COURSE CO
    ON TEA.TNO = CO.TNO
    WHERE TEA.TNAME='张旭'
) 
OPTION(FAST 1)

看看它的IO:

Table 'SCORE'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'COURSE'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'TEACHER'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

看看它的执行计划:

这基本就是我们想要的了。

关于FAST hint,联机文档是这么解释的:

其实也就是说FAST提示会将join优化为nested loop join ,而不用hash join,这样就能够快速的返回前几行/前几十行,尤其针对一个结果集会返回大量数据,但我们只需要显示前10行,那么如果hash join就不如nested loop join快了,当然,如果你要全部返回并显示,那么nested loop join就可能会比hash join还要慢了。