当 SQL Server 服务启动时,我需要在我的服务器上的 IIS 中回收一个 AppPool。
我采取的路线是有一个启动存储过程,它运行具有 Powershell 作业步骤的代理作业。
我已经从互联网上创建/抓取了一个 Powershell 脚本来回收应用程序池:
# Load IIS module:
Import-Module WebAdministration
# Set a name of the site we want to recycle the pool for:
$site = "Default Web Site"
# Get pool name by the site name:
$pool = (Get-Item "IIS:\Sites\$site"| Select-Object applicationPool).applicationPool
# Recycle the application pool:
Restart-WebAppPool $pool
Run Code Online (Sandbox Code Playgroud)
这适用于操作系统级别,但仅当 Powershell 以管理员身份运行时才有效(即使我在 Admin 组中登录到 Windows 的帐户也是如此)
果然,如果我使用包含上述代码的 Powershell 步骤在代理中创建作业,则在执行时会出现错误
作业步骤在 PowerShell 脚本的第 6 行收到错误。对应的行是'$pool = (Get-Item "IIS:\Sites\$site"| Select-Object applicationPool).applicationPool'。更正脚本并重新安排作业。PowerShell 返回的错误信息是:'无法检索 …
我正在使用 SentryOne 计划浏览器。
当我右键单击 SSMS 中的执行计划窗格时,第一个选项是
使用 SentryOne 计划浏览器查看
单击它会启动计划资源管理器的实例并打开执行计划。
如果我让计划资源管理器保持打开状态,然后在 SSMS 中运行另一个查询并右键单击“执行计划”窗格并再次单击“使用 SentryOne 计划资源管理器查看”,则不会发生任何事情。我原以为会打开一个新选项卡或 Plan Explorer 的新实例,或者在已经运行的实例中打开一个新选项卡?
我做错了什么还是这是一个功能?
我一直在阅读 Microsoft SQL 服务器中的应用程序角色。应用程序角色似乎与任何其他角色一样,可以将安全对象的权限授予应用程序角色,但是,不同之处在于它必须由使用存储过程的应用程序“调用” sp_setapprole。
我可以看到使用它的唯一原因是 DBA 允许应用程序(及其开发人员)连接到数据库,而不必提供服务器登录名或数据库用户,因此开发人员无法直接连接到 SQL Server(例如通过 SSMS),即使那样,我也看不到这样做的好处,因为提供给应用程序/开发人员的帐户肯定会被授予最低要求的权限吗?
我在这里错过了什么吗?
我已使用以下语法在我们的一台服务器上运行sp_WhoIsActive:
sp_whoisactive @get_plans = 1, @show_sleeping_spids = 0, @get_outer_command = 1, @get_locks = 1
Run Code Online (Sandbox Code Playgroud)
并用sql_command(显示的列@get_outer_command设置为1)找到了一个spid,如下所示
(@p1 int,@p2 int)
Exec MyDatabase.MyProc @p1 @p2
Run Code Online (Sandbox Code Playgroud)
当我尝试在我的测试 Adventureworks 数据库上使用此语法运行查询时:
(@be int)
SELECT *
FROM Person.Person
WHERE BusinessEntityID = @be
Run Code Online (Sandbox Code Playgroud)
我收到错误
消息 1050,级别 15,状态 1,第 1 行 此语法仅适用于参数化查询。消息 137,级别 15,状态 2,第 4 行 必须声明标量变量“@FN”。
所以这似乎与参数化查询有关。这是有道理的,因为变量 @be 永远不会被设置为一个值
这里发生了什么?
给定 StackOverflow2010 数据库上的以下简单查询:
SELECT u.DisplayName,
u.Reputation
FROM Users u
JOIN Posts p
ON u.id = p.OwnerUserId
WHERE u.DisplayName = 'alex' AND
p.CreationDate >= '2010-01-01' AND
p.CreationDate <= '2010-03-01'
Run Code Online (Sandbox Code Playgroud)
我试图理解为什么创建索引
CREATE INDEX IX_CreationDate ON Posts
(
CreationDate
)
INCLUDE (OwnerUserId)
Run Code Online (Sandbox Code Playgroud)
产生更好的估计Posts.CreationDate
当我运行没有索引的查询时,我得到Plan 1。在此计划中,SQL Server 估计 Posts 上的 CI 扫描产生 298,910 行,实际上返回 552 行 - 这个估计值相差甚远。
添加索引后,我会得到Plan 2,这会导致索引查找和更准确的估计。
我很好奇为什么添加索引会导致更好的估计,因为当在谓词中使用列时会创建统计信息WHERE,无论它是否被索引。
经过进一步检查,我可以看到计划 1 与计划 2 上的谓词Posts.CreationDate不同:
计划 1 谓词
[StackOverflow2010].[dbo].[Posts].[CreationDate] as [p].[CreationDate]>='2010-01-01 00:00:00.000' AND [StackOverflow2010].[dbo].[Posts].[CreationDate] …Run Code Online (Sandbox Code Playgroud) sql-server execution-plan database-internals cardinality-estimates sql-server-2019
我有一个查询,我在查询存储中强制执行一个计划(该计划是为此查询编译的 SQL Server)如果我在强制执行该计划后立即运行该查询,NO_PLAN尽管数据库没有发生任何更改,但我会得到last_force_failure_reason_desc。我可以成功地对同一查询强制执行不同的计划
这个问题可以用下图来说明:
创建我们的测试数据库
USE [master]
CREATE DATABASE NO_PLAN
ALTER DATABASE [NO_PLAN] SET QUERY_STORE = ON
ALTER DATABASE [NO_PLAN] SET QUERY_STORE (OPERATION_MODE = READ_WRITE, QUERY_CAPTURE_MODE = ALL)
GO
USE NO_PLAN
GO
IF EXISTS (SELECT 1 FROM sys.tables WHERE name = 'MyTableA') DROP TABLE MyTableA
IF EXISTS (SELECT 1 FROM sys.tables WHERE name = 'MyTableB') DROP TABLE MyTableB
/* create our tables */
CREATE TABLE [dbo].[MyTableA](
[Column1] VARCHAR(50) NULL ,
[Column2] VARCHAR(255) NULL ,
[Column3] INT NULL , …Run Code Online (Sandbox Code Playgroud) 我在我的系统上捕获了一个死锁,(匿名)XML 输出如下:
<deadlock>
<victim-list>
<victimProcess id="processf4d9233468" />
</victim-list>
<process-list>
<process id="processf4d9233468" taskpriority="0" logused="0" waitresource="KEY: 6:72057594039631872 (d117f90e375f)" waittime="481" ownerId="840005340" transactionname="SELECT" lasttranstarted="2019-10-14T10:16:07.550" XDES="0xeec803db90" lockMode="S" schedulerid="16" kpid="7220" status="suspended" spid="145" sbid="0" ecid="0" priority="0" trancount="0" lastbatchstarted="2019-10-14T10:16:07.547" lastbatchcompleted="2019-10-14T10:16:07.550" lastattention="1900-01-01T00:00:00.550" clientapp=".Net SqlClient Data Provider" hostname="MYWEBSERVER" hostpid="4512" loginname="MyOtherLogin" isolationlevel="read committed (2)" xactid="840005340" currentdb="6" currentdbname="MyDB" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack>
<frame procname="MyDB.MySchema.MyProc" line="13" stmtstart="670" stmtend="9106" sqlhandle="MYSQLHANDLE">
SELECT p.[Col25]
, p.Col1
, pId.Col2
, p.Col3
, p.Col4
, p.Col5
, CONVERT(VARCHAR(10),p.Col6,103)
, a.[Col7]
, a.[Col8]
, a.[Col9]
, a.[Col10]
, a.[Col11] …Run Code Online (Sandbox Code Playgroud) 我可以在 AdventureWorks 表 Person.Person 上创建以下约束:
ALTER TABLE Person.Person ADD CONSTRAINT ConstantScan CHECK (LastName <> N'Doesn''t Exist')
这告诉 SQL Server LastName 的值不能为Doesn't Exist
优化器在以下简单查询中利用了这一点:
SELECT *
FROM Person.Person
WHERE LastName = N'Doesn''t Exist'
Run Code Online (Sandbox Code Playgroud)
由于约束告诉优化器列中没有任何内容可以等于我们正在相等搜索的值(假设有可信约束),因此优化器仅执行持续扫描并且“不执行任何操作”
如果我放弃上面的约束并创建一个稍微不同的约束:
ALTER TABLE Person.Person ADD CONSTRAINT ConstantScan2 CHECK (LastName <> N'Doesn''t Exist' AND FirstName <> N'Doesn''t Exist')
并使用谓词运行查询,其结果将违反检查约束:
SELECT *
FROM Person.Person
WHERE FirstName = N'Doesn''t Exist' AND
LastName = N'Doesn''t Exist'
Run Code Online (Sandbox Code Playgroud)
我们通过键查找进行索引查找
但是,如果我跑
SELECT *
FROM Person.Person
WHERE FirstName = N'Doesn''t Exist' …Run Code Online (Sandbox Code Playgroud) sql-server constraint optimization sql-server-2019 query-performance
我在 StackOverflow 数据库中有以下 [相当无意义,仅用于演示] 查询:
SELECT *
FROM Users u
LEFT JOIN Comments c
ON u.Id = c.UserId OR
u.Id = c.PostId
WHERE u.DisplayName = 'alex'
Run Code Online (Sandbox Code Playgroud)
Users表上唯一的索引是 ID 上的聚集索引。
该Comments表具有以下非聚集索引以及 ID 上的聚集索引:
CREATE INDEX IX_UserID ON Comments
(
UserID,
PostID
)
CREATE INDEX IX_PostID ON Comments
(
PostID,
UserID
)
Run Code Online (Sandbox Code Playgroud)
查询的估计计划在这里:
我可以看到优化器将做的第一件事是对用户表执行 CI 扫描以仅过滤那些用户 where DisplayName = Alex,有效地执行此操作:
SELECT *
FROM Users u
WHERE u.DisplayName = 'alex'
ORDER BY Id
Run Code Online (Sandbox Code Playgroud)
并检索结果如下:
然后它会扫描评论 CI 并针对每一行,查看该行是否满足谓词 …
sql-server optimization execution-plan sql-server-2019 query-performance
我一直在做一些测试,试图更好地理解 SQL Server 如何使用直方图来估计与等式谓词以及 < 或 > 谓词匹配的行数
鉴于我正在使用AdventureWorks2016 OLTP 数据库
如果能够理解SQL Server对=和>谓词的估计过程:
/* update stats with fullscan first */
UPDATE STATISTICS Production.TransactionHistory WITH FULLSCAN
Run Code Online (Sandbox Code Playgroud)
然后我可以看到该列的直方图TransactionHistory.Quantity
DBCC SHOW_STATISTICS (
'Production.TransactionHistory',
'Quantity')
Run Code Online (Sandbox Code Playgroud)
下面的屏幕截图是我运行测试的直方图的顶端:
以下查询将估计 6 行,因为谓词中的值是 RANGE_HI_KEY,因此对该存储桶使用 EQ_ROWS:
SELECT *
FROM Production.TransactionHistory
WHERE Quantity = 2863
Run Code Online (Sandbox Code Playgroud)
以下将估计 1.36 行,因为它不是 RANGE_HI_KEY,因此使用 AVG_RANGE_ROWS 作为它所属的存储桶:
SELECT *
FROM Production.TransactionHistory
WHERE Quantity = 2862
Run Code Online (Sandbox Code Playgroud)
以下“大于”查询将估计 130 行,这似乎是 RANGE_HI_KEY > 2863 的所有存储桶的 RANGE_ROWS 和 EQ_ROWS 之和
SELECT *
FROM Production.TransactionHistory
WHERE Quantity > 2863 …Run Code Online (Sandbox Code Playgroud) statistics database-internals sql-server-2016 cardinality-estimates
sql-server ×8
optimization ×2
constraint ×1
deadlock ×1
hints ×1
locking ×1
parameter ×1
powershell ×1
query-store ×1
role ×1
security ×1
statistics ×1
syntax ×1