这更像是一个一般性问题,但这个问题的动机是我在使用 SQL Server 时遇到的一个问题。
我将此触发器附加到包含一些逻辑的表上的 Insert 事件,作为副作用,如果没有插入行,则会引发错误。经过进一步调查,我发现尽管没有插入行,但触发器仍在触发。
Microsoft Docs on DML Triggers 中使用的语言似乎与此行为相矛盾:
DML 触发器是一种特殊类型的存储过程,当发生影响触发器中定义的表或视图的 DML 事件时,它会自动生效。
这是跨 DBMS 的默认行为吗?当没有行受到影响时,是否有特殊原因触发触发器?
我正在处理这个我选择使用 CTE 的巨大查询。由于此查询的复杂性,我最终不得不在后续查询中多次重用中间查询结果。我面临的问题可以通过以下玩具代码进行总结:
WITH cte1 AS (
SELECT id, name
FROM Manager)
, cte2 AS (
SELECT id, name
FROM Employee
LEFT OUTER JOIN cte1 ON Employee.id = cte1.id)
SELECT *
FROM cte1
Run Code Online (Sandbox Code Playgroud)
我注意到在一个相当小的表中寻找异常数量的索引,该表在第一个查询中被查询,根据执行计划,占整个查询的大约 30%。这让我相信基表被多次查询,因为它在后续查询中被多次引用。
我的印象是 CTE 中的中间结果被缓存,直到最后的语句。阅读微软关于 CTE 的文档,我找不到任何理由不这么想。
中间 CTE 是否缓存用于WITH
语句中的多种用途?如果没有,有没有办法在不重写查询的情况下缓存它?
谢谢!
我有一个查询,我需要将一个有 5 行的小表交叉连接到一个大约有 31k 行的表。SQL Server 提出的执行计划在两个表中进行索引扫描,并将它们与嵌套循环 (INNER JOIN) 连接起来。但是,在检查执行计划时,我注意到对较小表的扫描为下一步生成了 5 x 31k = 155k 行。这是否意味着 SQL Server 正在扫描较小表的索引 31k 次?
这是我遇到的问题的小复制:
CREATE TABLE A (id INT PRIMARY KEY);
CREATE TABLE B (id INT PRIMARY KEY);
INSERT INTO A(id)
VALUES (1), (2), (3), (4), (5);
INSERT INTO B(id)
VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9)
SELECT * FROM A CROSS JOIN B
Run Code Online (Sandbox Code Playgroud)
我的问题是,小表上的索引扫描是否正在执行多个 I/O 操作,大表上的每一行一个,而不是只执行一次并且只将其结果提供给以下步骤一次。