SQL Server增加INSERT ... SELECT的物理读取

时间:2017-02-09 03:19:01

标签: sql-server tsql database-performance

版本1

INSERT INTO table_a (col_1, col_2)
SELECT DISTINCT col_1, col_2
FROM table_b b
WHERE b.col_1 IS NOT NULL
AND b.col_2 IS NOT NULL
AND b.id NOT IN
(
 SELECT b.id
 FROM table_b b
 JOIN table_a a WITH(NOLOCK)
 ON b.col_1 = a.col_1
 AND b.col_2 = a.col_2.
 )

第2版

SELECT * INTO #temp FROM
(
 SELECT DISTINCT col_1, col_2
 FROM table_b

 WHERE b.col_1 IS NOT NULL
 AND b.col_2 IS NOT NULL
 AND b.id NOT IN
(
 SELECT b.id
 FROM table_b b
 JOIN table_a a WITH(NOLOCK)
 ON b.col_1 = a.col_1
 AND b.col_2 = a.col_2
)) t

INSERT INTO table_a (col_1, col_2) SELECT col_1, col_2 FROM #temp

col_1:varchar col_2:varchar

table_a:群集在主键序列ID上,col_1上的非群集唯一包括col_2,col_2上的非群集唯一包括col_1

版本1 I / O

表'table_b'。扫描计数34,逻辑读取118,物理读取0,预读取读取0,lob逻辑读取0,lob物理读取0,lob预读读取0。 表'table_a'。扫描计数0,逻辑读取109404,物理读取8761,预读读取7761,lob逻辑读取0,lob物理读取0,lob预读读取0。 表'工作台'。扫描计数0,逻辑读取0,物理读取0,预读取读取0,lob逻辑读取0,lob物理读取0,lob预读读取0。

(4997行受影响)

版本2 I / O

表'table_b'。扫描计数34,逻辑读取118,物理读取0,预读取读取0,lob逻辑读取0,lob物理读取0,lob预读读取0。 表'table_a'。扫描计数0,逻辑读取35454,物理读取0,预读读取5435,lob逻辑读取0,lob物理读取0,lob预读读取0。 表'#temp _______________________________________________________________________________________________________________ 00000044D848'。扫描计数0,逻辑读取5045,物理读取0,预读取读取0,lob逻辑读取0,lob物理读取0,lob预读读取0。 表'工作台'。扫描计数0,逻辑读取0,物理读取0,预读取读取0,lob逻辑读取0,lob物理读取0,lob预读读取0。

(受影响的4994行)

(1行(s)受影响) 表'table_a'。扫描计数0,逻辑读取105486,物理读取331,预读读取5940,lob逻辑读取0,lob物理读取0,lob预读读取0。 表'工作台'。扫描计数2,逻辑读取10412,物理读取0,预读取读取0,lob逻辑读取0,lob物理读取0,lob预读读取0。 表'#temp _______________________________________________________________________________________________________________ 00000044D848'。扫描计数1,逻辑读取52,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0。

(受影响的4994行)

版本1比版本2慢得多,我假设由于物理读取次数较高。

有没有明显的理由说明为什么物理读数会如此不同,从表面上看,似乎两个版本应该做同样的工作。

我已经用冷热和缓存来运行这么多时间,并且在两个版本中都看到了一致的行为。

1 个答案:

答案 0 :(得分:0)

嘿,你可以尝试替代查询,

- 如果不需要,请删除distince

    SELECT DISTINCT col_1, col_2
FROM table_b b
WHERE b.col_1 IS NOT NULL
AND b.col_2 IS NOT NULL
AND not exists  
(
 SELECT a.id
 FROM table_a a WITH(NOLOCK)
 where b.col_1 = a.col_1
 AND b.col_2 = a.col_2.

 )
 --2nd query
 SELECT DISTINCT b.col_1, .col_2
 FROM table_b b
 JOIN table_a a WITH(NOLOCK)
 ON b.col_1 = a.col_1
 AND b.col_2 = a.col_2

最重要的是它是否需要输出?

试试这个,

ALTER INDEX ALL ON [table_a]
DISABLE;

INSERT INTO table_a (col_1, col_2)

SELECT DISTINCT b.col_1, .col_2
 FROM table_b b WITH(NOLOCK)
 JOIN table_a a WITH(NOLOCK)
 ON b.col_1 = a.col_1
 AND b.col_2 = a.col_2

ALTER INDEX ALL ON [TableName]
REBUILD;