方案:SQL Server 2014(v12.0.4100.1)
.NET服务运行以下查询:
SELECT name, base_object_name
FROM sys.synonyms
WHERE schema_id IN (SELECT schema_id
FROM sys.schemas
WHERE name = N'XXXX')
ORDER BY name
...返回约6500行,但通常会在3分钟后超时。的XXXX
上面是不 “DBO”。
如果我以UserA身份在SSMS中运行此查询,则查询将在不到一秒钟的时间内返回。
当以UserB身份运行(这是.NET服务的连接方式)时,查询需要3到6 分钟的时间,并且整个时间的CPU%占25%(4核)。
UserA是sysadmin角色中的域登录名。
UserB是具有以下内容的SQL登录名:
EXEC sp_addrolemember N'db_datareader', N'UserB'
EXEC sp_addrolemember N'db_datawriter', N'UserB'
EXEC sp_addrolemember N'db_ddladmin', N'UserB'
GRANT EXECUTE TO [UserB]
GRANT CREATE SCHEMA TO [UserB]
GRANT VIEW DEFINITION TO [UserB]
我可以通过将上述SQL封装在一个Execute as...Revert
块中来在SSMS中复制此代码,因此.NET代码不在图片之内。
执行计划看起来相同。我对XML进行了差异化处理,只有微小的差异(CompileTime,CompileCPU,CompileMemory)。
IO统计信息均未显示任何物理读取:
表'sysobjvalues'。扫描计数为0,逻辑读取为19970,物理读取为0,预读为0,lob逻辑读取为0,lob物理读取为0,lob提前读取为0。 表“工作文件”。扫描计数0,逻辑读0,物理读0,预读0,lob逻辑读0,lob物理读0,lob预读0。 表“工作表”。扫描计数0,逻辑读0,物理读0,预读0,lob逻辑读0,lob物理读0,lob预读0。 表'sysschobjs'。扫描计数1,逻辑读9122,物理读0,预读0,lob逻辑读0,lob物理读0,lob预读0。 表'sysclsobjs'。扫描计数0,逻辑读2,物理读0,预读0,lob逻辑读0,lob物理读0,lob预读0。
XEvent等待状态(约3分钟的查询)为:
+ --------------------- + ------------ + -------------- -------- + ------------------------------ + ---------- ------------------- + | 等待类型 等待计数| 总等待时间(毫秒)| 总资源等待时间(毫秒)| 总信号等待时间(毫秒)| + --------------------- + ------------ + -------------- -------- + ------------------------------- + --------- -------------------- + | SOS_SCHEDULER_YIELD | 37300 | 427 | 20 | 407 | | NETWORK_IO | 5 | 26 | 26 | 0 | | IO_COMPLETION | 3 | 1 | 1 | 0 | + --------------------- + ------------ + -------------- -------- + ------------------------------- + --------- -------------------- +
如果我重写查询(在SSMS中,我无权访问应用代码)以
declare @id int
SELECT @id=schema_id FROM sys.schemas WHERE name = N'XXXX'
SELECT a.name, base_object_name FROM sys.synonyms a
WHERE schema_id = @id
ORDER BY name
然后UserB以与UserA相同(快速)的速度运行。
如果我添加db_owner
到UserB,则查询再次运行<1秒。
通过此模板创建的架构:
DECLARE @TranName VARCHAR(20)
SELECT @TranName = 'MyTransaction'
BEGIN TRANSACTION @TranName
GO
IF NOT EXISTS (SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
WHERE SCHEMA_NAME = '{1}')
BEGIN
EXEC('CREATE SCHEMA [{1}]')
EXEC sp_addextendedproperty @name='User', @value='{0}', @level0type=N'Schema', @level0name=N'{1}'
END
GO
{2}
COMMIT TRANSACTION MyTransaction;
GO
我相信{2}是在该架构中创建的同义词列表。
查询配置文件进入查询的两点:
我已经和微软开了张票。
另外,我们尝试将UserB添加到中db_owner
,然后获取DENY
与关联的所有已知特权db_owner
。结果是快速查询。我们要么错过了某件事(完全有可能),要么对该db_owner
角色进行了特殊检查。