Sql-Server
SQL Profiler 顯示一個 TVF 的多個呼叫
我注意到 SQL Profiler 中有一個表值函式,它似乎*“多次呼叫自身”*。
該定義也沒有做任何奇怪的事情,它是一個很少的查詢
JOINs
和WHERE
帶有hierarchyid方法的子句IsDescendantOf
這裡發生了什麼?難道只是虛驚一場?
你怎麼認為?
提前致謝
SQL:批量啟動
exec sp_executesql N'SELECT * FROM [dbo].[GetPermissionsForUser](@p0) ',N'@p0 uniqueidentifier',@p0='7A2137C1-A7D4-415C-A5B5-F4C2351217C9'
SP:開始和 SP:已完成
SELECT * FROM [dbo].[GetPermissionsForUser](@p0)
架構
CREATE TABLE [dbo].[permission_matrix] ( [Id] [uniqueidentifier] NOT NULL, [TargetId] [uniqueidentifier] NULL, [Permission] [nvarchar](35) NOT NULL, [GroupId] [uniqueidentifier] NULL, [Options] [int] NOT NULL, CONSTRAINT [PK_permission] PRIMARY KEY CLUSTERED ([Id] ASC) CREATE TABLE [dbo].[hierarchy]( [NodeId] [int] IDENTITY(1,1) NOT NULL, [EntityId] [uniqueidentifier] NOT NULL, [EntityType] [smallint] NOT NULL, [ParentEntityId] [uniqueidentifier] NULL, [NodePath] [hierarchyid] NOT NULL, CONSTRAINT [PK_hierarchy] PRIMARY KEY NONCLUSTERED ([NodeId] ASC) CREATE FUNCTION [dbo].[GetPermissionsForUser] ( @userId UNIQUEIDENTIFIER ) RETURNS TABLE AS RETURN ( SELECT op.Id, op.TargetId, op.Permission, op.GroupId, op.Options FROM [dbo].[permission_matrix] op WHERE EXISTS( SELECT 1 FROM [dbo].[hierarchy] gh JOIN [dbo].[hierarchy] uh ON uh.EntityId = @userId AND uh.NodePath.IsDescendantOf(gh.NodePath) = 1 WHERE gh.EntityId = op.GroupId) )
這就是 SQL Profiler 中顯示的內容
- 編輯
擴展事件會話不顯示
我的第一反應是:不要使用 Profiler。由於一長串原因,它在十多年前就被棄用了;這個特定的症狀不是最重要的,但有幾個,正如我在這篇文章中所闡述的:
一個更好的選擇是擴展事件。我嘗試使用XEvent Profiler中包含的基本 TSQL 會話來重現您的場景,並準確地看到對該函式的一次呼叫。
至於“為什麼”:
我懷疑 Profiler 正在為每一行(或每一個匹配的行)報告一個函式呼叫的實例,其中涉及的底層機制
IsDescendantOf
必須是遞歸的。我的好朋友Andy Mallon提醒我,它
hierarchyid
是在停止對 Profiler 的投資很久之後才發明的,所以它沒有正確地忽略噪音對我來說並不奇怪。我敢打賭,如果您在函式中註釋掉該行,那麼症狀就會消失,儘管由於其他層次結構遍歷,它仍然可能會發生。但即使你證實,這仍然是完全的猜測。如果您想要一個正式的答案,您可以嘗試向 Microsoft 提供支持案例,但我不知道他們是否會接聽電話 - 他們可能會告訴您我告訴您的內容:使用擴展事件。