加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程 > 正文

sql-server – 为什么子查询使用并行性而不是连接?

发布时间:2020-12-31 23:47:12 所属栏目:编程 来源:网络整理
导读:为什么SQL Server在运行行使子查询的查询时会行使并行性,但在行使毗连时却否则?毗连版本以串行方法运行,完成时刻约莫必要30倍. 插手版本:~30secs 子查询版本: 1秒 编辑: Xml版本的查询打算: JOIN version SUBQUERY version 办理要领 正如评述中已经指出

为什么SQL Server在运行行使子查询的查询时会行使并行性,但在行使毗连时却否则?毗连版本以串行方法运行,完成时刻约莫必要30倍.

插手版本:~30secs

子查询版本:< 1秒 编辑:
Xml版本的查询打算:

JOIN version

SUBQUERY version

办理要领

正如评述中已经指出的那样,您好像必要更新统计信息.

从位置和测试之间的毗连中出来的预计行数在两个打算之间长短常差异的.

插手打算估算:1

子查询打算预计:8,748

从毗连中出来的现实施数是14,276.

虽然,绝对没有直觉意味着毗连版本应该预计3行应该来自位置并发生单个毗连行,而子查询预计这些行中的单个行将从统一毗连发生8,748可是我如故是可以或许重现这一点.

假如在建设统计信息时直方图之间没有交错,则好像会产生这种环境.毗连版本假定为单行.而且子查询的单个相称性查找假设与对未知变量的相称性搜刮沟通的预计行.

测试的基数是26244.假设有三个差异的位置ID,则以下查询预计将返回8,748行(26244/3)

declare @i int

SELECT *
FROM   testruns AS tr
WHERE  tr.location_id = @i

鉴于表位置只包括3行,很轻易(假如我们假设没有外键)来计划建设统计信息的环境,然后以显著影响返回的现实施数但不敷的方法变动数据跳转统计信息的自动更新并从头编译阈值.

因为SQL Server获取了来自该毗连的行数以是错误,因此毗连打算中的全部其他行预计都被大大低估了.除了意味着您得到了一个串行打算之外,查询还得到了不敷的内存授权,而且排序和散列毗连溢出到tempdb.

重现打算中表现的现实施与预计行的一种也许方案如下.

CREATE TABLE location
  (
     id       INT CONSTRAINT locationpk PRIMARY KEY,location VARCHAR(MAX) /*From the separate filter think you are using max?*/
  )

/*Temporary ids these will be updated later*/
INSERT INTO location
VALUES      (101,'Coventry'),(102,'Nottingham'),(103,'Derby')

CREATE TABLE testruns
  (
     location_id INT
  )

CREATE CLUSTERED INDEX IX ON testruns(location_id)

/*Add in 26244 rows of data split over three ids*/
INSERT INTO testruns
SELECT TOP (5984) 1
FROM   master..spt_values v1,master..spt_values v2
UNION ALL
SELECT TOP (5984) 2
FROM   master..spt_values v1,master..spt_values v2
UNION ALL
SELECT TOP (14276) 3
FROM   master..spt_values v1,master..spt_values v2

/*Create statistics. The location_id histograms don't intersect at all*/
UPDATE STATISTICS location(locationpk) WITH FULLSCAN;    
UPDATE STATISTICS testruns(IX) WITH FULLSCAN;

/* UPDATE location.id. Three row update is below recompile threshold*/
UPDATE location
SET    id = id - 100

然后运行以下查询给出沟通的预计与现实差别

SELECT *
FROM   testruns AS tr
WHERE  tr.location_id = (SELECT id
                         FROM   location
                         WHERE  location = 'Derby')

SELECT *
FROM   testruns AS tr
       JOIN location loc
         ON tr.location_id = loc.id
WHERE  loc.location = ( 'Derby' )

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读