在 SQL 服务器中限制用户查询的大小 and/or 频率
Limit size and/or frequency of user queries in SQL Server
是否可以在 SQL 服务器(或其他引擎)中限制用户查询的“大小”和频率?例如:
假设有几张表有数百万行。也许有一些管理员和分析师在处理表格,他们知道自己的方法,不会 运行 任何不必要的繁重查询,这些查询可能 运行 几个 minutes/hours.
然而,sales/marketers/admin 不太熟悉 SQL 的员工更有可能 运行 繁重的查询,例如有大量的连接,无论是偶然的还是只是为了好玩。乘以几十,服务器可被重创
理想情况下,我想要如下限制:
- 如果引擎预计会有超过一百万行扫描,则取消查询(并告诉用户取消查询的原因)。
- 将单个用户 运行 的查询限制为 10 分钟内 20 个查询 window。
- User/role-level“上限”
您对代码执行的要求相当激进。没有什么开箱即用的东西可以为您工作。但是,您可以实施某些事情来实现您在此处尝试实现的目标:
不要让用户直接访问 tables,创建 procs 并且只授予对 procs 的访问权。
在 procs 中,您可以通过添加 top 子句来限制用户可以 return 的最大行数。
创建审计 table 并在每次用户调用过程时在过程中向该审计添加一行 table,第一步也可以是检查调用者的该过程的审计 table 中已经有多少行(用户已经执行了多少次过程)并在用户已经超过限制等时引发错误。你得到想法。
我建议不要限制查询的成本,这会回来困扰你,出于多种原因,请自己或你信任的人编写 queries/Procs 来编写高效的代码。
像这样....
CREATE PROC dbo.usp_Test
AS
BEGIN
SET NOCOUNT ON;
Declare @UserCalls INT;
SELECT @UserCalls = Count(*)
FROM dbo.AuditTable
WHERE UserName = SUSER_SNAME()
AND ProcName = 'usp_Test'
AND Logged >= DATEADD(MINUTE , -1 , GETDATE());
IF (@UserCalls >= 10)
BEGIN
RAISERROR ('Come back in 1 minute, you have exceeded 10 execution/min limit' , 16 , 1);
RETURN;
END
ELSE
BEGIN
INSERT INTO dbo.Audit (ProcName , UserName , Logged)
VALUES ('usp_Test' , SUSER_SNAME() , GETDATE());
END
/* Rest of the code */
SELECT TOP (1000) *
FROM ...........;
END
您要查找的功能称为 Resource Governor。
您可以对传入的连接进行分类并将它们分配给一个 Workload Group,它指定
CREATE WORKLOAD GROUP group_name
[ WITH
( [ IMPORTANCE = { LOW | MEDIUM | HIGH } ]
[ [ , ] REQUEST_MAX_MEMORY_GRANT_PERCENT = value ]
[ [ , ] REQUEST_MAX_CPU_TIME_SEC = value ]
[ [ , ] REQUEST_MEMORY_GRANT_TIMEOUT_SEC = value ]
[ [ , ] MAX_DOP = value ]
[ [ , ] GROUP_MAX_REQUESTS = value ] )
]
[ USING {
[ pool_name | "default" ]
[ [ , ] EXTERNAL external_pool_name | "default" ] ]
} ]
[ ; ]
并映射到对服务器资源的访问权限有限的Resource Pool。
In the SQL Server Resource Governor, a resource pool represents a
subset of the physical resources of an instance of the Database
Engine. Resource Governor enables you to specify limits on the amount
of CPU, physical IO, and memory that incoming application requests can
use within the resource pool. Each resource pool can contain one or
more workload groups.
将 Resource Governor 与报告用户的 snapshot-based 读取相结合非常重要,可以使用 SNAPSHOT 隔离,或将数据库设置为 READ_COMMITTED_SNAPSHOT。否则,对资源访问权限有限的报告用户可能会获取干扰其他工作负载的锁。
是否可以在 SQL 服务器(或其他引擎)中限制用户查询的“大小”和频率?例如:
假设有几张表有数百万行。也许有一些管理员和分析师在处理表格,他们知道自己的方法,不会 运行 任何不必要的繁重查询,这些查询可能 运行 几个 minutes/hours.
然而,sales/marketers/admin 不太熟悉 SQL 的员工更有可能 运行 繁重的查询,例如有大量的连接,无论是偶然的还是只是为了好玩。乘以几十,服务器可被重创
理想情况下,我想要如下限制:
- 如果引擎预计会有超过一百万行扫描,则取消查询(并告诉用户取消查询的原因)。
- 将单个用户 运行 的查询限制为 10 分钟内 20 个查询 window。
- User/role-level“上限”
您对代码执行的要求相当激进。没有什么开箱即用的东西可以为您工作。但是,您可以实施某些事情来实现您在此处尝试实现的目标:
不要让用户直接访问 tables,创建 procs 并且只授予对 procs 的访问权。
在 procs 中,您可以通过添加 top 子句来限制用户可以 return 的最大行数。
创建审计 table 并在每次用户调用过程时在过程中向该审计添加一行 table,第一步也可以是检查调用者的该过程的审计 table 中已经有多少行(用户已经执行了多少次过程)并在用户已经超过限制等时引发错误。你得到想法。
我建议不要限制查询的成本,这会回来困扰你,出于多种原因,请自己或你信任的人编写 queries/Procs 来编写高效的代码。
像这样....
CREATE PROC dbo.usp_Test
AS
BEGIN
SET NOCOUNT ON;
Declare @UserCalls INT;
SELECT @UserCalls = Count(*)
FROM dbo.AuditTable
WHERE UserName = SUSER_SNAME()
AND ProcName = 'usp_Test'
AND Logged >= DATEADD(MINUTE , -1 , GETDATE());
IF (@UserCalls >= 10)
BEGIN
RAISERROR ('Come back in 1 minute, you have exceeded 10 execution/min limit' , 16 , 1);
RETURN;
END
ELSE
BEGIN
INSERT INTO dbo.Audit (ProcName , UserName , Logged)
VALUES ('usp_Test' , SUSER_SNAME() , GETDATE());
END
/* Rest of the code */
SELECT TOP (1000) *
FROM ...........;
END
您要查找的功能称为 Resource Governor。
您可以对传入的连接进行分类并将它们分配给一个 Workload Group,它指定
CREATE WORKLOAD GROUP group_name
[ WITH
( [ IMPORTANCE = { LOW | MEDIUM | HIGH } ]
[ [ , ] REQUEST_MAX_MEMORY_GRANT_PERCENT = value ]
[ [ , ] REQUEST_MAX_CPU_TIME_SEC = value ]
[ [ , ] REQUEST_MEMORY_GRANT_TIMEOUT_SEC = value ]
[ [ , ] MAX_DOP = value ]
[ [ , ] GROUP_MAX_REQUESTS = value ] )
]
[ USING {
[ pool_name | "default" ]
[ [ , ] EXTERNAL external_pool_name | "default" ] ]
} ]
[ ; ]
并映射到对服务器资源的访问权限有限的Resource Pool。
In the SQL Server Resource Governor, a resource pool represents a subset of the physical resources of an instance of the Database Engine. Resource Governor enables you to specify limits on the amount of CPU, physical IO, and memory that incoming application requests can use within the resource pool. Each resource pool can contain one or more workload groups.
将 Resource Governor 与报告用户的 snapshot-based 读取相结合非常重要,可以使用 SNAPSHOT 隔离,或将数据库设置为 READ_COMMITTED_SNAPSHOT。否则,对资源访问权限有限的报告用户可能会获取干扰其他工作负载的锁。