这里我们有两个类似的查询,使用grouping sets
whereSELECT子句包含一些在聚合中计算的表达式:
SELECT RN10, RN10 / 10, COUNT(*) FROM
(
SELECT RN, RN/10 AS RN10, RN/100 AS RN100 FROM
(
SELECT RN = -1 + ROW_NUMBER() OVER (ORDER BY 1/0)
FROM master..spt_values
) A
) B
GROUP BY GROUPING SETS ((RN10), (RN10 / 10), ())
ORDER BY 1, 2
Run Code Online (Sandbox Code Playgroud)
它的计划在这里:第一个查询计划
和
SELECT RN10, SUBSTRING(RN,3,99), COUNT(*) FROM
(
SELECT RN, SUBSTRING(RN,2,99) AS RN10 FROM
(
SELECT RN = CAST(-1 + ROW_NUMBER() OVER (ORDER BY 1/0) AS …Run Code Online (Sandbox Code Playgroud) 这是一个小的repro:
create table dbo.t (id int primary key, v int);
insert into dbo.t values (1, 1), (2, 2);
create table dbo.s (id int primary key, v int);
insert into dbo.s values (1, 10);
go
create trigger dbo.tr_t__iou
on dbo.t
instead of update
as
begin
set nocount on;
exec sp_lock @@spid;
end;
go
update dbo.t set v = 10 where id = 1;
update t
set
v = 10
from
dbo.s s join
dbo.t t on t.id = s.id;
update t …Run Code Online (Sandbox Code Playgroud) 这是我在SQL Server 2008 R2, 2012,上测试过的复制品2016。
第二个和第三个查询确实使用了RowCount Spool,为什么第一个没有?
create table dbo.t (id int identity primary key, v int);
--create statistics ST_t__v on dbo.t(v) with norecompute;
insert into dbo.t (v)
select top (10000) rand(checksum(newid())) * 5
from master.dbo.spt_values a cross join
master.dbo.spt_values b;
go
declare @v int;
set statistics xml, io on;
select @v = v from dbo.t where exists(select 1 from dbo.t where v = 4);
select @v = v from dbo.t where exists(select …Run Code Online (Sandbox Code Playgroud) 在下面的例子中,结果Index Spool已经排序,为什么我们Top N Sort这里有而不是简单的Top?
use tempdb;
go
create table dbo.t1 (id int identity primary key, v int);
create table dbo.t2 (id int identity primary key, v int);
insert into dbo.t1
(v)
select top (1000)
row_number() over (order by 1/0)
from
master.dbo.spt_values a cross join
master.dbo.spt_values b;
insert into dbo.t2
(v)
select top (10000)
row_number() over (order by 1/0) + 10000
from
master.dbo.spt_values a cross join
master.dbo.spt_values b;
set statistics xml, io on;
select
sum(a.v …Run Code Online (Sandbox Code Playgroud) 我继承了一个应用程序在sysadmin帐户下运行的系统。我限制该帐户db_datareader+ db_datawriter+EXECUTE上的所有数据库和一套extended events会议赶permission errors在服务器上。即使用户是其中的成员并且对表没有应用细粒度限制
,看到一些inserts失败也让我感到非常惊讶db_datawriter。
然后我注意到只有该集合的插入IDENTITY_INSERT失败。有问题的数据库是满的identity,有太多SET IDENTITY_INSERT在他们的代码。代码不仅意味着modules存储在服务器上,还意味着C#代码。
要能够设置identity_insert用户必须拥有该表或对该表具有ALTER权限。但事实是你不能ALTER只授予表,我被迫授予ALTER整个数据库的权限(user
我会让这个用户的db_ddladmin角色成员只添加42 个权限(!!!) vs 51 个可以通过授予ALTER数据库添加到用户权限)
我对重构数据库不感兴趣sequence(服务器版本是2014这样我理论上可以做到)而且我不能只是添加execute as dbo到每个使用的 sp 中,identity_insert因为还有应用程序代码要重写,我只是想知道为什么微软会做出如此奇怪的事情db_datawriter无法设置的权限设计identity_insert? …
sql-server ×5
optimization ×2
group-by ×1
identity ×1
locking ×1
permissions ×1
security ×1
t-sql ×1
trigger ×1