我的执行计划的 table 扫描运算符中的这一列 [Bmk1002] 是什么?
What's this column [Bmk1002] in the table scan operator of my execution plan?
我有一个简单的脚本。
IF OBJECT_ID('dbo.Customers', 'U') IS NOT NULL
DROP TABLE dbo.Customers;
GO
CREATE TABLE dbo.Customers
(
custid INT NOT NULL,
companyname VARCHAR(125) NOT NULL,
phone VARCHAR(120) NOT NULL,
address VARCHAR(150) NOT NULL
);
INSERT INTO dbo.Customers
(custid, companyname, phone, address)
VALUES (1, 'cust 1', '(111) 111-1111', 'address 1'),
(2, 'cust 2', '(222) 222-2222', 'address 2'),
(3, 'cust 3', '(333) 333-3333', 'address 3'),
(4, 'cust 4', '(444) 444-4444', 'address 4'),
(5, 'cust 5', '(555) 555-5555', 'address 5');
IF OBJECT_ID('dbo.CustomersStage', 'U') IS NOT NULL
DROP TABLE dbo.CustomersStage;
GO
CREATE TABLE dbo.CustomersStage
(
custid INT NOT NULL,
companyname VARCHAR(125) NOT NULL,
phone VARCHAR(120) NOT NULL,
address VARCHAR(150) NOT NULL
);
INSERT INTO dbo.CustomersStage
(custid, companyname, phone, address)
VALUES (2, 'AAAAA', '(222) 222-2222', 'address 2'),
(1, 'cust 1111111111', '(111) 111-11111111111111', 'address 111111111'),
-- (1, 'cust 1111111112222222222', '(111) 111-1111111112222222222', 'address 1111111112222222222'),
(3, 'cust 3', '(333) 333-3333', 'address 3'),
(5, 'BBBBB', 'CCCCC', 'DDDDD'),
(6, 'cust 6 (new)', '(666) 666-6666', 'address 6'),
(7, 'cust 7 (new)', '(777) 777-7777', 'address 7');
SELECT *
FROM dbo.Customers;
SELECT *
FROM dbo.CustomersStage;
SET STATISTICS XML ON;
MERGE INTO dbo.Customers d
USING dbo.CustomersStage s
ON d.custid = s.custid
WHEN MATCHED THEN
UPDATE SET d.companyname = s.companyname,
d.phone = s.phone,
d.address = s.address
WHEN NOT MATCHED THEN
INSERT (
custid,
companyname,
phone,
address
)
VALUES (
s.custid,
s.companyname,
s.phone,
s.address
);
SET STATISTICS XML OFF;
SELECT *
FROM dbo.Customers;
MERGE
语句的执行计划如下所示。
您可以在此处下载执行计划 https://drive.google.com/file/d/0B4xMAUd6DN6XdkZyTmJkdF9TY3c/view?
我的问题是,这个 [Bmk1002] 到底是什么?希望有人能帮忙解释一下。
Bmkxxxx 是附加列,未在查询中引用。
它是来自 tablescan 的键值,它将在查询执行的后续部分中使用。查看 Red-gate 的这本优秀电子书,了解有关执行计划的更多信息。 http://download.red-gate.com/ebooks/SQL/eBOOK_SQLServerExecutionPlans_2Ed_G_Fritchey.pdf
并从 SQL Sentry 下载此工具以帮助您导航执行计划。
http://www.sqlsentry.com/products/plan-explorer/sql-server-query-view
Pluralsight 的这门课程非常棒。
https://www.pluralsight.com/courses/sqlserver-query-plan-analysis
就是"bookmark"(也指"bookmark lookup"这句)。
这是行的物理位置(文件:页面:槽位)。
客户是一堆
SELECT %%lockres%%
FROM Customers
将向您显示这些值(如果它有聚簇索引,您可以使用 %%physloc%%
代替,但原始输出并不那么友好)。
此执行计划中需要它,因为合并规范要求它在尝试多次更新或删除同一行时抛出错误。
因为没有其他可用的唯一键SQL服务器使用此书签作为保证能够唯一标识一行的值。
该计划计算 ROW_NUMBER() OVER (PARTITION BY Bmk1002 ORDER BY Bmk1002)
* 并且断言运算符会在出现 >1
时引发错误(如果dbo.CustomersStage 连接到 dbo.Customers) 中的同一个。
* 实际上计划调用 conditional_row_number
而不是 row_number
。这是一个内部未记录的功能。我想它使用条件版本而不是直接 row_number
因为它需要在检查重复项时忽略具有 "insert" 操作的行。
我有一个简单的脚本。
IF OBJECT_ID('dbo.Customers', 'U') IS NOT NULL
DROP TABLE dbo.Customers;
GO
CREATE TABLE dbo.Customers
(
custid INT NOT NULL,
companyname VARCHAR(125) NOT NULL,
phone VARCHAR(120) NOT NULL,
address VARCHAR(150) NOT NULL
);
INSERT INTO dbo.Customers
(custid, companyname, phone, address)
VALUES (1, 'cust 1', '(111) 111-1111', 'address 1'),
(2, 'cust 2', '(222) 222-2222', 'address 2'),
(3, 'cust 3', '(333) 333-3333', 'address 3'),
(4, 'cust 4', '(444) 444-4444', 'address 4'),
(5, 'cust 5', '(555) 555-5555', 'address 5');
IF OBJECT_ID('dbo.CustomersStage', 'U') IS NOT NULL
DROP TABLE dbo.CustomersStage;
GO
CREATE TABLE dbo.CustomersStage
(
custid INT NOT NULL,
companyname VARCHAR(125) NOT NULL,
phone VARCHAR(120) NOT NULL,
address VARCHAR(150) NOT NULL
);
INSERT INTO dbo.CustomersStage
(custid, companyname, phone, address)
VALUES (2, 'AAAAA', '(222) 222-2222', 'address 2'),
(1, 'cust 1111111111', '(111) 111-11111111111111', 'address 111111111'),
-- (1, 'cust 1111111112222222222', '(111) 111-1111111112222222222', 'address 1111111112222222222'),
(3, 'cust 3', '(333) 333-3333', 'address 3'),
(5, 'BBBBB', 'CCCCC', 'DDDDD'),
(6, 'cust 6 (new)', '(666) 666-6666', 'address 6'),
(7, 'cust 7 (new)', '(777) 777-7777', 'address 7');
SELECT *
FROM dbo.Customers;
SELECT *
FROM dbo.CustomersStage;
SET STATISTICS XML ON;
MERGE INTO dbo.Customers d
USING dbo.CustomersStage s
ON d.custid = s.custid
WHEN MATCHED THEN
UPDATE SET d.companyname = s.companyname,
d.phone = s.phone,
d.address = s.address
WHEN NOT MATCHED THEN
INSERT (
custid,
companyname,
phone,
address
)
VALUES (
s.custid,
s.companyname,
s.phone,
s.address
);
SET STATISTICS XML OFF;
SELECT *
FROM dbo.Customers;
MERGE
语句的执行计划如下所示。
您可以在此处下载执行计划 https://drive.google.com/file/d/0B4xMAUd6DN6XdkZyTmJkdF9TY3c/view?
我的问题是,这个 [Bmk1002] 到底是什么?希望有人能帮忙解释一下。
Bmkxxxx 是附加列,未在查询中引用。 它是来自 tablescan 的键值,它将在查询执行的后续部分中使用。查看 Red-gate 的这本优秀电子书,了解有关执行计划的更多信息。 http://download.red-gate.com/ebooks/SQL/eBOOK_SQLServerExecutionPlans_2Ed_G_Fritchey.pdf
并从 SQL Sentry 下载此工具以帮助您导航执行计划。 http://www.sqlsentry.com/products/plan-explorer/sql-server-query-view
Pluralsight 的这门课程非常棒。 https://www.pluralsight.com/courses/sqlserver-query-plan-analysis
就是"bookmark"(也指"bookmark lookup"这句)。
这是行的物理位置(文件:页面:槽位)。
客户是一堆
SELECT %%lockres%%
FROM Customers
将向您显示这些值(如果它有聚簇索引,您可以使用 %%physloc%%
代替,但原始输出并不那么友好)。
此执行计划中需要它,因为合并规范要求它在尝试多次更新或删除同一行时抛出错误。
因为没有其他可用的唯一键SQL服务器使用此书签作为保证能够唯一标识一行的值。
该计划计算 ROW_NUMBER() OVER (PARTITION BY Bmk1002 ORDER BY Bmk1002)
* 并且断言运算符会在出现 >1
时引发错误(如果dbo.CustomersStage 连接到 dbo.Customers) 中的同一个。
* 实际上计划调用 conditional_row_number
而不是 row_number
。这是一个内部未记录的功能。我想它使用条件版本而不是直接 row_number
因为它需要在检查重复项时忽略具有 "insert" 操作的行。