我遇到了一个奇怪的问题,SQL Server 2016 标准版 64 位似乎将自己限制在分配给它的总内存的一半(128GB 中的 64GB)。
的输出@@VERSION
是:
Microsoft SQL Server 2016 (SP1-CU7-GDR) (KB4057119) - 13.0.4466.4 (X64) 2017 年 12 月 22 日 11:25:00 版权所有 (c) Windows Server 2012 R2 Datacenter 6.3 上的 Microsoft Corporation 标准版(64 位)(内部版本 9600:)(管理程序)
的输出sys.dm_os_process_memory
是:
当我查询时sys.dm_os_performance_counters
,我看到Target Server Memory (KB)
是在131072000
和Total Server Memory (KB)
是 at 的一半以下65308016
。在大多数情况下,我认为这是正常行为,因为 SQL Server 尚未确定它需要为自己分配更多内存。
然而,它已经“卡住”在 64GB 左右超过 2 个月了。在此期间,我们对一些数据库执行了大量内存密集型操作,并向实例添加了近 40 个数据库。我们总共有 292 个数据库,每个数据库都有 4GB 的预分配数据文件和 256MB 的自动增长速率和 2GB …
我们开始为 VMware 中的 SQL Server 2016 节点虚拟集群提供一组物理服务器。我们将使用企业版许可证。
我们计划设置 6 个节点,但关于在 CPU 时钟速度与 CPU 核心数方面配置物理服务器的理想方式存在一些争论。
我知道这在很大程度上取决于交易量和存储的数据库数量以及其他特定于软件的因素,但是否有建议的一般经验法则?
例如,双 8 核 3.2 GHz 物理服务器(16 核)是否比双 16 核 2.6 GHz 服务器(32 核)更优惠?
有没有人遇到过进一步深入研究此类主题的白皮书?
我有一个基本[UserActivity]
表,它捕获了一个ActivityTypeId
perUserId
和ActivityDate
发生 Activity 的时间。
我写一个查询/存储过程中允许的输入@UserId
,@ForTypeId
,还有@DurationInterval
和@DurationIncrement
基于动态返回的结果ň若干秒/分钟/小时/天/月/年。鉴于其中的datepart
参数DATEADD/DATEDIFF
不允许使用参数,为了在WHERE
子句中获得所需的结果,我不得不重新使用一些技巧。
最初我使用 编写查询DATEDIFF
,但在编写并查看执行计划后,我立即想起它不是 SARGable 函数(以及精度级别可以为闰年下降的某些日期提供的事实)。因此,我重新编写了查询以利用DATEPART
我会命中索引查找而不是索引扫描并且通常性能更好的想法。
不幸的是,我发现将查询编写为DATEADD
提供了相同的结果:正在执行索引扫描,并且查询优化器没有针对[ActivityDate]
.
我读阿龙贝特朗的博客文章,“业绩惊喜和假设:DATEADD”,并实现了他描述的变化CONVERT
的DATEADD
部分成等价的datetime2
,由于涉及怪异弄虚作假列定义datetime2
。但是,即使这样做了,问题仍然存在。
为了更好地说明这种情况,这里有一个可比较的表定义。
DROP TABLE IF EXISTS [dbo].[UserActivity]
IF OBJECT_ID('[dbo].[UserActivity]', 'U') IS NULL
BEGIN
CREATE TABLE [dbo].[UserActivity] (
[UserId] [int] NOT NULL
,[UserActivityId] [bigint] IDENTITY(1,1) NOT NULL
,[ActivityTypeId] [tinyint] NOT …
Run Code Online (Sandbox Code Playgroud) performance index sql-server execution-plan query-performance
在我的 SQL Server 日志中,我显示从一个SERVER\loginname
在Security > Logins
OR 中找不到的帐户 ( )成功登录到数据库Database > Security > Users
。程序正在使用此登录名来执行任务(它成功完成),因此这不是安全隐患,但我终生无法弄清楚它在哪里,我需要找到它来进行调整。
还有一些注意事项:我确实记得不久前添加了这个特定的登录名,并且我必须这样做有一些特别之处,因为它不是域帐户。相反,它使用传递身份验证(应用程序和 SQL 服务器上的相同本地帐户名称和相同的密码)。我无法使用它通过 SSMS 登录。它不是组成员资格的一部分。当我SELECT
从主syslogins
表做 a 时它没有显示。
有人对我的脑放屁有什么想法吗?
我有一个表,用于捕获用户正在运行的主机平台。该表的定义很简单:
IF OBJECT_ID('[Auth].[ActivityPlatform]', 'U') IS NULL
BEGIN
CREATE TABLE [Auth].[ActivityPlatform] (
[ActivityPlatformId] [tinyint] IDENTITY(1,1) NOT NULL
,[ActivityPlatformName] [varchar](32) NOT NULL
,CONSTRAINT [PK_ActivityPlatform] PRIMARY KEY CLUSTERED ([ActivityPlatformId] ASC)
,CONSTRAINT [UQ_ActivityPlatform_ActivityPlatformName] UNIQUE NONCLUSTERED ([ActivityPlatformName] ASC)
) ON [Auth];
END;
GO
Run Code Online (Sandbox Code Playgroud)
它存储的数据是基于 JavaScript 方法枚举的,该方法使用来自浏览器的信息(我不知道更多,但可以在需要时找到):
但是,当我在SELECT
没有显式的情况下执行基本操作ORDER BY
时,执行计划显示它正在使用UNIQUE NONCLUSTERED
索引而不是CLUSTERED
索引进行排序。
SELECT * FROM [Auth].[ActivityPlatform]
Run Code Online (Sandbox Code Playgroud)
当显式指定 时ORDER BY
,它正确地按 排序ActivityPlatformId
。
SELECT * FROM [Auth].[ActivityPlatform] ORDER BY [ActivityPlatformId]
Run Code Online (Sandbox Code Playgroud)
DBCC SHOWCONTIG('[Auth].[ActivityPlatform]') WITH ALL_LEVELS, TABLERESULTS
显示没有表碎片。
我错过了什么可能导致这个?我一直认为该表是在聚集索引上创建的,它应该自动隐式地对其进行排序,而无需指定ORDER BY …
performance index sql-server execution-plan query-performance
我正在尝试更新使用子句谓词中的IN
运算符的查询,以比较潜在的性能改进并更好地了解当两者互换时幕后发生的事情。这是我的理解,在实践中,查询优化器对待,并以同样的方式时,它可以。WHERE
EXISTS
EXISTS
IN
我注意到当使用IN
运算符运行查询时,它返回所需的结果集。但是,当我用EXISTS
等效项替换它时,它会从我要过滤的主表中提取所有值。它忽略传递给EXISTS (SELECT ...
并返回所有可能的不同值的提供的输入值。
用例相对简单:查询接受一个管道分隔的@Series
字符串,最多可以包含 4 个值,例如S1|S2|S3|S4
或S2|S4
。在这里,我string_split
将输入到一个表中的变量@SeriesSplit
,以确定相应的内部[SeriesId]
的[Series]
。然后过滤返回的结果集以排除[Series]
未通过的结果。
为了说明,这里有一个类似的表定义:
DROP TABLE IF EXISTS [dbo].[Document]
IF OBJECT_ID('[dbo].[Document]', 'U') IS NULL
BEGIN
CREATE TABLE [dbo].[Document] (
[DocumentId] bigint IDENTITY(1,1) NOT NULL
,[DocumentSeriesId] [tinyint] NOT NULL
,CONSTRAINT [PK_Document] PRIMARY KEY CLUSTERED ([DocumentId] ASC)
,INDEX [IX_Document_SeriesId] NONCLUSTERED ([DocumentSeriesId] ASC)
);
END;
GO
Run Code Online (Sandbox Code Playgroud)
用虚拟数据填充测试表。
SET IDENTITY_INSERT [dbo].[Document] ON; …
Run Code Online (Sandbox Code Playgroud) performance sql-server execution-plan sql-server-2016 query-performance
LTRIM
与RTRIM
结合使用时,您放置的操作顺序是否重要ISNULL
?例如,以下面的示例为例,用户可能会在字段中输入一堆空格,但我们将其输入修剪为实际NULL
值以避免存储空字符串。
我正在执行以下TRIM
操作ISNULL
:
DECLARE @Test1 varchar(16) = ' '
IF LTRIM(RTRIM(ISNULL(@Test1,''))) = ''
BEGIN
SET @Test1 = NULL
END
SELECT @Test1
Run Code Online (Sandbox Code Playgroud)
这适当地返回一个真NULL
值。现在让我们ISNULL
放在外面:
DECLARE @Test2 varchar(16) = ' '
IF ISNULL(LTRIM(RTRIM(@Test2)),'') = ''
BEGIN
SET @Test2 = NULL
END
SELECT @Test2
Run Code Online (Sandbox Code Playgroud)
这也返回一个NULL
值。两者都适用于预期用途,但我很好奇 SQL 查询优化器处理此问题的方式是否有任何不同?
我想利用基于 a 的分区[TenantId]
(稍后与日期范围结合使用)。我不需要在 中手动插入最新值PARTITION FUNCTION
,而是考虑创建一个TRIGGER AFTER INSERT
来提取[TenantId]
值并将ALTER PARTITION FUNCTION
其添加到 中SPLIT RANGE
。然而,我遇到了一个意想不到的错误:
无法对/使用表“租户”执行 ALTER PARTITION FUNCTION,因为该表是目标表或当前正在执行的触发器的级联操作的一部分。
首先,我创建PARTITION FUNCTION [PF_Tenant_Isolation]
和PARTITION SCHEME [PS_Tenant_Isolation]
以便在 上进行分区[TenantId]
。
CREATE PARTITION FUNCTION [PF_Tenant_Isolation] ([int])
AS RANGE LEFT FOR VALUES (1);
GO
CREATE PARTITION SCHEME [PS_Tenant_Isolation]
AS PARTITION [PF_Tenant_Isolation]
ALL TO ([Auth]);
GO
Run Code Online (Sandbox Code Playgroud)
接下来,我将[Tenant]
根据新创建的分区方案创建表。
IF OBJECT_ID('[Auth].[Tenant]', 'U') IS NULL
BEGIN
CREATE TABLE [Auth].[Tenant] (
[TenantId] [int] IDENTITY(1,1)
,[TenantActive] [bit] …
Run Code Online (Sandbox Code Playgroud) sql-server ×8
performance ×6
index ×2
clustering ×1
hardware ×1
memory ×1
optimization ×1
partitioning ×1
security ×1
sp-blitz ×1
t-sql ×1
vmware ×1