AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / user-37801

PicoDeGallo's questions

Martin Hope
PicoDeGallo
Asked: 2019-03-06 15:54:59 +0800 CST

复合主键中定义的列的非聚集索引

  • 3

我有一个多租户数据库,我在其中使用AccountId所有表中的列作为用于租户隔离的复合主键的一部分。在作为复合主键的一部分的每个列上创建额外的非聚集索引以帮助 SQL Server 在连接到查找表时维护准确的统计信息并提高查询性能是否有益?

例如,在一个关联表中,该关联表定义了一个人和他们在其中设有办公室Account的美国人之间的一对多关系,在给定以下结构和示例查询的情况下,理论上这两个选项中的哪一个更可取?State

创建Account和State表并填充示例数据。

DROP TABLE IF EXISTS [dbo].[Account];
DROP TABLE IF EXISTS [dbo].[State];

-- [Account] table and sample values.
IF OBJECT_ID('[dbo].[Account]', 'U') IS NULL
BEGIN
    CREATE TABLE [dbo].[Account] (
        [AccountId] [int] IDENTITY(1,1) NOT NULL
        ,[AccountAlias] [varchar](3) NOT NULL
        ,[AccountName] [varchar](128) NOT NULL
        ,CONSTRAINT [PK_Account] PRIMARY KEY CLUSTERED ([AccountId] ASC)
        ,CONSTRAINT [UQ_Account_Alias] UNIQUE NONCLUSTERED ([AccountAlias] ASC)
        ,CONSTRAINT [UQ_Account_Name] UNIQUE NONCLUSTERED ([AccountName] ASC)
    );

    SET IDENTITY_INSERT [dbo].[Account] ON;

    INSERT INTO [dbo].[Account] ([AccountId], [AccountAlias], [AccountName])
    VALUES (1, 'SA1', 'Sample Account 1'), (2, 'SA2', 'Sample Account 2'), (3, 'SA3', 'Sample Account 3')

    SET IDENTITY_INSERT [dbo].[Account] OFF;
END;
GO

-- [State] table and sample values.
IF OBJECT_ID('[dbo].[State]', 'U') IS NULL
BEGIN
    CREATE TABLE [dbo].[State] (
        [StateId] [tinyint] IDENTITY(1,1) NOT NULL
        ,[StateCode] [varchar](2) NOT NULL
        ,[StateName] [varchar](32) NOT NULL
        ,CONSTRAINT [PK_State] PRIMARY KEY CLUSTERED ([StateId] ASC)
        ,CONSTRAINT [UQ_State_Code] UNIQUE NONCLUSTERED ([StateCode] ASC)
        ,CONSTRAINT [UQ_State_Name] UNIQUE NONCLUSTERED ([StateName] ASC)
    );

    SET IDENTITY_INSERT [dbo].[State] ON;

    INSERT INTO [dbo].[State] ([StateId], [StateCode], [StateName])
    VALUES (1, 'AL', 'Alabama'), (2, 'AK', 'Alaska'), (3, 'AZ', 'Arizona'), (4, 'AR', 'Arkansas'), (5, 'CA', 'California')

    SET IDENTITY_INSERT [dbo].[State] OFF;
END;
GO

创建AccountState选项 1 - 仅复合主键

DROP TABLE IF EXISTS [dbo].[AccountState];

IF OBJECT_ID('[dbo].[AccountState]', 'U') IS NULL
BEGIN
    CREATE TABLE [dbo].[AccountState] (
        [AccountId] [int] NOT NULL
        ,[StateId] [tinyint] NOT NULL
        ,CONSTRAINT [PK_AccountState] PRIMARY KEY CLUSTERED ([AccountId] ASC, [StateId] ASC)
        ,CONSTRAINT [FK_AccountState_Account] FOREIGN KEY ([AccountId]) REFERENCES [dbo].[Account]([AccountId])
        ,CONSTRAINT [FK_AccountState_State] FOREIGN KEY ([StateId]) REFERENCES [dbo].[State]([StateId])
    );

    INSERT INTO [dbo].[AccountState] ([AccountId], [StateId])
    SELECT A.[AccountId], S.[StateId]
    FROM [dbo].[Account] A CROSS JOIN [dbo].[State] S
    WHERE A.[AccountId] = 1 AND S.[StateId] IN (1, 2, 3)
    UNION
    SELECT A.[AccountId], S.[StateId]
    FROM [dbo].[Account] A CROSS JOIN [dbo].[State] S
    WHERE A.[AccountId] = 2 AND S.[StateId] IN (3, 4, 5)
    UNION
    SELECT A.[AccountId], S.[StateId]
    FROM [dbo].[Account] A CROSS JOIN [dbo].[State] S
    WHERE A.[AccountId] = 3 AND S.[StateId] IN (1, 3, 5)
END;
GO

创建AccountState选项 2 - 复合主键 + 非聚集索引

DROP TABLE IF EXISTS [dbo].[AccountState];

IF OBJECT_ID('[dbo].[AccountState]', 'U') IS NULL
BEGIN
    CREATE TABLE [dbo].[AccountState] (
        [AccountId] [int] NOT NULL
        ,[StateId] [tinyint] NOT NULL
        ,CONSTRAINT [PK_AccountState] PRIMARY KEY CLUSTERED ([AccountId] ASC, [StateId] ASC)
        ,CONSTRAINT [FK_AccountState_Account] FOREIGN KEY ([AccountId]) REFERENCES [dbo].[Account]([AccountId])
        ,CONSTRAINT [FK_AccountState_State] FOREIGN KEY ([StateId]) REFERENCES [dbo].[State]([StateId])
        ,INDEX [IX_AccountState_Account] NONCLUSTERED ([AccountId])
        ,INDEX [IX_AccountState_State] NONCLUSTERED ([StateId])
    );

    INSERT INTO [dbo].[AccountState] ([AccountId], [StateId])
    SELECT A.[AccountId], S.[StateId]
    FROM [dbo].[Account] A CROSS JOIN [dbo].[State] S
    WHERE A.[AccountId] = 1 AND S.[StateId] IN (1, 2, 3)
    UNION
    SELECT A.[AccountId], S.[StateId]
    FROM [dbo].[Account] A CROSS JOIN [dbo].[State] S
    WHERE A.[AccountId] = 2 AND S.[StateId] IN (3, 4, 5)
    UNION
    SELECT A.[AccountId], S.[StateId]
    FROM [dbo].[Account] A CROSS JOIN [dbo].[State] S
    WHERE A.[AccountId] = 3 AND S.[StateId] IN (1, 3, 5)
END;
GO

样本查询

SELECT
    A.[AccountName]
    ,S.[StateName]
FROM
    [dbo].[AccountState] A_S
    JOIN [dbo].[Account] A
        ON A_S.[AccountId] = A.[AccountId]
    JOIN [dbo].[State] S
        ON A_S.[StateId] = S.[StateId]
WHERE
    S.[StateCode] = 'CA'

在这两个选项中,哪种类型的指数组合最适合扩展?仅复合主键或复合主键加其他非聚集索引?或者还有其他更可行的选择吗?

sql-server database-design
  • 1 个回答
  • 751 Views
Martin Hope
PicoDeGallo
Asked: 2018-06-20 13:19:35 +0800 CST

LTRIM/RTRIM/ISNULL 的操作顺序

  • 2

结合使用时您放置的操作顺序是否LTRIM重要?例如,以下面的示例为例,用户可能在字段中输入一堆空格,但我们将他们的输入修剪为实际值以避免存储空字符串。RTRIMISNULLNULL

我正在执行以下TRIM操作ISNULL:

DECLARE @Test1 varchar(16) = '    '

IF LTRIM(RTRIM(ISNULL(@Test1,''))) = ''
BEGIN
    SET @Test1 = NULL
END

SELECT @Test1

这会适当地返回一个真NULL值。现在让我们放在ISNULL外面:

DECLARE @Test2 varchar(16) = '    '

IF ISNULL(LTRIM(RTRIM(@Test2)),'') = ''
BEGIN
    SET @Test2 = NULL
END

SELECT @Test2

这也返回一个NULL值。两者都适用于预期用途,但我很好奇 SQL 查询优化器如何处理这个有什么不同?

sql-server t-sql
  • 2 个回答
  • 5677 Views
Martin Hope
PicoDeGallo
Asked: 2018-04-17 07:51:31 +0800 CST

SQL Server 的“总服务器内存”消耗数月停滞不前,但可用容量超过 64GB

  • 40

我遇到了一个奇怪的问题,SQL Server 2016 标准版 64 位似乎已经将自己限制在分配给它的总内存的一半(64GB 的 128GB)。

的输出@@VERSION是:

Microsoft SQL Server 2016 (SP1-CU7-GDR) (KB4057119) - 13.0.4466.4 (X64) 2017 年 12 月 22 日 11:25:00 版权所有 (c) Microsoft Corporation Standard Edition (64-bit) o​​n Windows Server 2012 R2 Datacenter 6.3 (内部版本 9600:)(管理程序)

的输出sys.dm_os_process_memory是:

sys.dm_os_process_memory

当我查询时sys.dm_os_performance_counters,我看到Target Server Memory (KB)是 at131072000并且Total Server Memory (KB)是 at 的一半以下65308016。在大多数情况下,我认为这是正常行为,因为 SQL Server 尚未确定它需要为自己分配更多内存。

但是,它已经“卡在”~64GB 两个多月了。在此期间,我们对一些数据库执行了大量内存密集型操作,并向实例添加了近 40 个数据库。我们总共有 292 个数据库,每个数据库的预分配数据文件为 4GB,自动增长速度为 256MB,日志文件为 2GB,自动增长速度为 128MB。我每晚在上午 12:00 执行一次完整备份,并从周一到周五从上午 6:00 到晚上 8:00 开始每隔 15 分钟进行一次事务日志备份。这些数据库的整体吞吐量相对较低,但我怀疑有些事情是错误的,因为 SQL Server 还没有爬上Target Server Memory自然地通过新的数据库添加、正常的查询执行以及已经运行的内存密集型 ETL 管道。

SQL Server 实例本身位于一个虚拟化 (VMware) Windows Server 2012R2 服务器之上,该服务器具有 12 个 CPU、144GB 内存(128GB 到 SQL Server,16GB 为 Windows 保留)和 4 个虚拟磁盘,这些虚拟磁盘位于具有 15K SAS 驱动器的 vSAN 之上. Windows 自然位于 64GB C: 磁盘上,页面文件为 32GB。数据文件位于 2TB D: 磁盘上,日志文件位于 2TB L: 磁盘之上,而 tempdb 位于 256GB T: 磁盘上,其中包含 8x16GB 文件,没有自动增长。

我已经验证除了MSSQLSERVER.

服务

此服务器完全专用于 SQL Server 实例,因此我们没有在其上运行可能会消耗内存的其他应用程序或服务。

资源监视器

我使用 RedGate SQL Monitor 进行分析,下面是过去 18 天的Total Server Memory. 如您所见,除了 4 月初单次上升约 300MB 之外,内存利用率一直完全停滞不前。

RedGate SQL 监视器

这可能是什么原因?为了确定为什么 SQL Server 不想使用分配给它的额外 64GB+ 内存,我可以仔细查看什么?

运行的输出sp_Blitz:

sp_Blitz @OutputType = 'markdown', @CheckServerInfo = 1;

优先级 50:性能:

  • CPU 调度程序脱机 - 由于关联屏蔽或许可问题,SQL Server 无法访问某些 CPU 内核。

  • 内存节点脱机 - 由于关联屏蔽或许可问题,某些内存可能不可用。

优先级 50:可靠性:

  • 远程 DAC 已禁用 - 未启用对专用管理员连接 (DAC) 的远程访问。当 SQL Server 无响应时,DAC 可以更轻松地进行远程故障排除。

优先级 100:性能:

  • 一个查询的许多计划 - 计划缓存中的单个查询存在 300 个计划 - 这意味着我们可能存在参数化问题。

  • 启用服务器触发器

    • 服务器触发器 [RG_SQLLighthouse_DDLTrigger] 已启用。确保您了解触发器在做什么——它做的工作越少越好。

    • 服务器触发器 [SSMSRemoteBlock] 已启用。确保您了解触发器在做什么——它做的工作越少越好。

优先级 150:性能:

  • 强制加入提示的查询 - 自重启以来已记录了 1480 个加入提示实例。这意味着查询支配着 SQL Server 优化器,如果他们不知道自己在做什么,这可能弊大于利。这也可以解释为什么 DBA 调优工作不起作用。

  • 查询强制订单提示 - 自重启以来已记录 2153 个订单提示实例。这意味着查询支配着 SQL Server 优化器,如果他们不知道自己在做什么,这可能弊大于利。这也可以解释为什么 DBA 调优工作不起作用。

优先级 170:文件配置:

  • C盘系统数据库

    • master - master 数据库在 C 驱动器上有一个文件。将系统数据库放在 C 驱动器上可能会在服务器空间不足时导致服务器崩溃。

    • 模型 - 模型数据库在 C 驱动器上有一个文件。将系统数据库放在 C 驱动器上可能会在服务器空间不足时导致服务器崩溃。

    • msdb - msdb 数据库在 C 驱动器上有一个文件。将系统数据库放在 C 驱动器上可能会在服务器空间不足时导致服务器崩溃。

优先级 200:信息:

  • 代理作业同时启动 - 多个 SQL Server 代理作业配置为同时启动。有关详细的时间表列表,请参阅 URL 中的查询。

  • Master 数据库 master 中的表 - master 数据库中的 CommandLog 表由最终用户于 2017 年 7 月 30 日下午 5:22 创建。发生灾难时,主数据库中的表可能无法恢复。

  • TraceFlag 开启

    • 跟踪标志 1118 全局启用。

    • 跟踪标志 1222 全局启用。

    • 跟踪标志 2371 已全局启用。

优先级 200:非默认服务器配置:

  • 代理 XP - 此 sp_configure 选项已更改。它的默认值为 0,并已设置为 1。

  • 备份校验和默认值 - 此 sp_configure 选项已更改。它的默认值为 0,并已设置为 1。

  • 备份压缩默认值 - 此 sp_configure 选项已更改。它的默认值为 0,并已设置为 1。

  • 并行度的成本阈值 - 此 sp_configure 选项已更改。它的默认值为 5,已设置为 48。

  • max degree of parallelism - 此 sp_configure 选项已更改。它的默认值为 0,已设置为 12。

  • 最大服务器内存 (MB) - 此 sp_configure 选项已更改。其默认值为 2147483647,已设置为 128000。

  • 针对临时工作负载进行优化 - 此 sp_configure 选项已更改。它的默认值为 0,并已设置为 1。

  • 显示高级选项 - 此 sp_configure 选项已更改。它的默认值为 0,并已设置为 1。

  • xp_cmdshell - 此 sp_configure 选项已更改。它的默认值为 0,并已设置为 1。

优先级 200:可靠性:

  • Master中的扩展存储过程

  • master - [sqbdata] 扩展存储过程位于 master 数据库中。CLR 可能正在使用中,并且主数据库现在需要成为您的备份/恢复计划的一部分。

    • master - [sqbdir] 扩展存储过程位于 master 数据库中。CLR 可能正在使用中,并且主数据库现在需要成为您的备份/恢复计划的一部分。

    • master - [sqbmemory] ​​扩展存储过程位于 master 数据库中。CLR 可能正在使用中,并且主数据库现在需要成为您的备份/恢复计划的一部分。

    • master - [sqbstatus] 扩展存储过程位于 master 数据库中。CLR 可能正在使用中,并且主数据库现在需要成为您的备份/恢复计划的一部分。

    • master - [sqbtest] 扩展存储过程位于 master 数据库中。CLR 可能正在使用中,并且主数据库现在需要成为您的备份/恢复计划的一部分。

    • master - [sqbtestcancel] 扩展存储过程位于 master 数据库中。CLR 可能正在使用中,并且主数据库现在需要成为您的备份/恢复计划的一部分。

    • master - [sqbteststatus] 扩展存储过程位于 master 数据库中。CLR 可能正在使用中,并且主数据库现在需要成为您的备份/恢复计划的一部分。

    • master - [sqbutility] 扩展存储过程位于 master 数据库中。CLR 可能正在使用中,并且主数据库现在需要成为您的备份/恢复计划的一部分。

    • master - [sqlbackup] 扩展存储过程位于 master 数据库中。CLR 可能正在使用中,并且主数据库现在需要成为您的备份/恢复计划的一部分。

优先级 210:非默认数据库配置:

  • Read Committed Snapshot Isolation Enabled - 此数据库设置不是默认设置。

    • 红门

    • 红门监视器

  • 启用快照隔离 - 此数据库设置不是默认设置。

    • 红门

    • 红门监视器

优先级 240:等待统计:

  • 1 - SOS_SCHEDULER_YIELD - 1770.8 小时等待,115.9 分钟平均每小时等待时间,100.0% 信号等待,1419212079 个等待任务,4.5 毫秒平均等待时间。

优先级 250:信息:

  • SQL Server 在 NT 服务帐户下运行 - 我作为 NT Service\MSSQLSERVER 运行。我希望我有一个 Active Directory 服务帐户。

优先级 250:服务器信息:

  • 默认跟踪内容 - 默认跟踪包含 2018 年 4 月 14 日晚上 11:21 到 2018 年 4 月 16 日上午 11:13 之间的 36 小时数据。默认跟踪文件位于:C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Log

  • 驱动器 C 空间 - C 驱动器上有 196816.00MB 可用空间

  • 驱动器 D 空间 - E 驱动器上有 894823.00MB 可用空间

  • 驱动器 L 空间 - F 驱动器上有 1361367.00MB 可用空间

  • 驱动器 T 空间 - G 驱动器上有 114441.00MB 可用空间

  • 硬件 - 逻辑处理器:12 个。物理内存:144GB。

  • 硬件 - NUMA 配置

    • 节点:0 状态:ONLINE 在线调度程序:4 离线调度程序:2 处理器组:0 内存节点:0 内存 VAS 保留 GB:186

    • 节点:1 状态:OFFLINE 在线调度程序:0 离线调度程序:6 处理器组:0 内存节点:0 内存 VAS 保留 GB:186

  • 已启用即时文件初始化 - 服务帐户具有执行卷维护任务权限。

  • 电源计划 - 你的服务器有 2.60GHz 的 CPU,并且处于平衡电源模式——呃......你希望你的 CPU 全速运行,对吗?

  • 服务器上次重启 - 2018 年 3 月 9 日上午 7:27

  • 服务器名称 - [已编辑]

  • 服务

    • 服务:SQL Server (MSSQLSERVER) 在服务帐户 NT Service\MSSQLSERVER 下运行。上次启动时间:2018 年 3 月 9 日上午 7:27。启动类型:自动,当前正在运行。

    • 服务:SQL Server 代理 (MSSQLSERVER) 在服务帐户 LocalSystem 下运行。上次启动时间:未显示。启动类型:自动,当前正在运行。

  • SQL Server 上次重新启动 - 2018 年 3 月 9 日上午 6:27

  • SQL Server 服务 - 版本:13.0.4466.4。补丁级别:SP1。累积更新:CU7。版本:标准版(64 位)。启用的可用性组:0。可用性组管理器状态:2

  • 虚拟服务器 - 类型:(HYPERVISOR)

  • Windows 版本 - 您正在运行一个非常现代的 Windows 版本:Server 2012R2 时代,版本 6.3

优先级 254:运行日期:

  • 船长的日志:给某事和某事约会……
sql-server performance
  • 3 个回答
  • 5881 Views
Martin Hope
PicoDeGallo
Asked: 2018-04-05 13:01:49 +0800 CST

将 IN 与 EXISTS 互换会产生不同的结果集

  • 4

我正在尝试更新一个查询,该查询利用子句谓词中的IN运算符来比较潜在的性能改进,并更好地了解当两者互换时幕后发生的事情。据我了解,在实践中,查询优化器会尽可能以相同的方式对待and 。WHEREEXISTSEXISTSIN

我注意到当使用IN运算符运行查询时,它会返回所需的结果集。但是,当我用等效项替换它时EXISTS,它会从我要过滤的主表中提取所有值。它忽略传递给的提供的输入值EXISTS (SELECT ...并返回所有可能的不同值。

用例相对简单:查询接受一个竖线分隔的@Series字符串,该字符串最多可以包含 4 个值,例如S1|S2|S3|S4or 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

用虚拟数据填充测试表。

SET IDENTITY_INSERT [dbo].[Document] ON;
;WITH [DocumentSeed] AS (
    SELECT
        1 AS [DocumentId]
    UNION ALL
    SELECT
        [DocumentId] + 1
    FROM
        [DocumentSeed]
    WHERE
        [DocumentId] < 2048)

INSERT INTO [dbo].[Document] ([DocumentId], [DocumentSeriesId])
SELECT
    [DocumentId]
    ,ABS(CHECKSUM(NEWID()) % 4) + 1
FROM
    [DocumentSeed] OPTION (MAXRECURSION 2048);
SET IDENTITY_INSERT [dbo].[Document] OFF;

首先,使用IN运算符并返回所需结果的查询。

-- Specify the Document Series to be returned.
DECLARE @Series varchar(12) = 'S1|S2'
-- Split the user input and insert it into a table variable.
DECLARE @SeriesSplit table ([SeriesId] tinyint, [Series] varchar(2))
BEGIN
INSERT INTO @SeriesSplit ([SeriesId], [Series])
SELECT
    CASE [value] WHEN 'S1' THEN 1 WHEN 'S2' THEN 2 WHEN 'S3' THEN 3 WHEN 'S4' THEN 4 ELSE 5 END AS [SeriesId]
    ,LTRIM(RTRIM([value])) AS [Series]
FROM
    string_split(@Series,'|')
WHERE
    [value] <> ''
END;

-- Return the result set of desired [DocumentSeriesId]
-- In the real use case, DISTINCT is not used and more columns are returned.
-- However, to illustrate the issue at hand, return only the [DocumentSeriesId] as this is what we are filtering off.
SELECT DISTINCT
    D1.[DocumentSeriesId]
FROM
    [dbo].[Document] D1
WHERE
    D1.[DocumentSeriesId] IN (SELECT SS.[SeriesId] FROM @SeriesSplit SS)

根据需要输出两行。执行计划 (PasteThePlan)显示它执行 aDistinct Sort以过滤适当的行。

如果我将WHERE子句更改为 utilize EXISTS,我会看到所有四种可能的结果,即使我已设置只返回两种结果。

-- Specify the Document Series to be returned.
DECLARE @Series varchar(14) = 'S1|S2'
-- Split the user input and insert it into a table variable.
DECLARE @SeriesSplit table ([SeriesId] tinyint, [Series] varchar(4))
BEGIN
INSERT INTO @SeriesSplit ([SeriesId], [Series])
SELECT
    CASE [value] WHEN 'S1' THEN 1 WHEN 'S2' THEN 2 WHEN 'S3' THEN 3 WHEN 'S4' THEN 4 ELSE 5 END AS [SeriesId]
    ,LTRIM(RTRIM([value])) AS [Series]
FROM
    string_split(@Series,'|')
WHERE
    [value] <> ''
END;

-- Return the result set of desired [DocumentSeriesId]
-- In the real use case, DISTINCT is not used and more columns are returned.
-- However, to illustrate the issue at hand, return only the [DocumentSeriesId] as this is what we are filtering off.
SELECT DISTINCT
    D1.[DocumentSeriesId]
FROM
    [dbo].[Document] D1
WHERE
    EXISTS (SELECT SS.[SeriesId] FROM @SeriesSplit SS JOIN [dbo].[Document] D2 ON SS.[SeriesId] = D2.[DocumentSeriesId])

执行计划 (PasteThePlan)因这个小改动而大不相同。它正在抛出谓词中存在的警告No Join Predicate。Left Semi Join我的假设是WHERE EXISTS ...隐含地满足这个论点,就像它对WHERE [DocumentSeriesId] IN .... 但是,假设Left Semi Join运算符在第二个输入中存在匹配行时返回初始输入中的每一行,并且由于No Join Predicate警告存在,查询优化器假定每一行都是匹配行。因此,所有后续批处理操作都针对表中的所有 2048 行运行。

我可以研究什么来更好地解释执行计划所描述的内容,以便我可以了解如何正确解决问题?

或者,在EXISTS基于静态输入过滤结果集时,我是否只是忽略了运算符的目的?

sql-server performance
  • 1 个回答
  • 156 Views
Martin Hope
PicoDeGallo
Asked: 2018-03-28 06:59:25 +0800 CST

DATEADD 不产生索引查找的 SARGable 期望

  • 7

我有一个基本[UserActivity]表,用于捕获活动发生的ActivityTypeId时间UserId和地点。ActivityDate

我正在编写一个查询/存储过程,允许输入@UserId,@ForTypeId以及@DurationInterval和 并@DurationIncrement根据N秒/分钟/小时/天/月/年的数量动态返回结果。鉴于datepart内部DATEADD/DATEDIFF参数不允许参数,我不得不恢复一些技巧才能在WHERE子句中获得所需的结果。

最初我使用 编写查询DATEDIFF,但在编写并查看执行计划后,我立即记起它不是 SARGable 函数(以及精度级别可以提供闰年下降的某些日期这一事实)。因此,我重新编写了查询,以利用DATEPART我会命中索引查找而不是索引扫描的想法,并且通常表现得更好。

不幸的是,我发现编写查询DATEADD提供了相同的结果:正在进行索引扫描,并且查询优化器没有利用针对[ActivityDate].

我阅读了Aaron Bertrand 的博客文章“性能惊喜和假设:DATEADD”,并CONVERT由于. 但是,即使这样做了,问题仍然存在。DATEADDdatetime2datetime2

为了更好地说明该场景,这里有一个可比较的表定义。

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 NULL
        ,[ActivityDate] [datetime2](0) NOT NULL CONSTRAINT [DF_UserActivity_ActivityDate] DEFAULT GETDATE()
        ,CONSTRAINT [PK_UserActivity] PRIMARY KEY CLUSTERED ([UserActivityId] ASC)
        ,INDEX [IX_UserActivity_UserId] NONCLUSTERED ([UserId] ASC)
        ,INDEX [IX_UserActivity_ActivityTypeId] NONCLUSTERED ([ActivityTypeId] ASC)
        ,INDEX [IX_UserActivity_ActivityDate] NONCLUSTERED ([ActivityDate] ASC)
    )
END;
GO

为 5 个不同的用户递归地用虚拟数据填充表,随机数ActivityTypeId在 1 到 10 之间,ActivityDate每 4 分钟一个新的。

DECLARE @UserId int = (SELECT ISNULL((SELECT TOP (1) [UserId] + 1 FROM [dbo].[UserActivity] ORDER BY [UserId] DESC), 1))
;WITH [UserActivitySeed] AS (
    SELECT
        CONVERT(datetime2(0), '01/01/2018') AS 'ActivityDate'
    UNION ALL
    SELECT
        DATEADD(minute, 4, [ActivityDate])
    FROM
        [UserActivitySeed]
    WHERE
        [ActivityDate] < '2018-04-01')
INSERT INTO [dbo].[UserActivity] ([UserId], [ActivityTypeId], [ActivityDate])
SELECT
    @UserId
    ,ABS(CHECKSUM(NEWID()) % 9) + 1
    ,[ActivityDate]
FROM
    [UserActivitySeed] OPTION (MAXRECURSION 32767);

GO 5

ALTER INDEX ALL ON [dbo].[UserActivity] REBUILD;

下面是我用 编写的第一个查询DATEDIFF。请注意,我有意排除了@UserId和@ForTypeId谓词,以避免那些关键查找并减少附加计划中的噪音。

正如您将在PasteThePlan 上针对此查询发现的那样,它正在按预期执行索引扫描,因为它DATEDIFF不是 SARGable。

DECLARE @UserId int = 1
DECLARE @ForTypeId int = 3
DECLARE @DurationInterval varchar(6) = 'hour'
DECLARE @DurationIncrement int = 1

SELECT
    COUNT(UA.[UserActivityId]) AS 'ActivityTypeCount'
FROM
    [dbo].[UserActivity] UA
WHERE
    -- Exclude the @UserId and @ForTypeId predicates.
    -- UA.[UserId] = @UserId
    -- AND UA.[ActivityTypeId] = @ForTypeId
    -- AND 
    CASE
        WHEN @DurationInterval IN ('year', 'yy', 'yyyy') THEN DATEDIFF(SECOND, UA.[ActivityDate], GETDATE()) / 3600.0 / 24.0 / 365.25
        WHEN @DurationInterval IN ('month', 'mm', 'm') THEN DATEDIFF(SECOND, UA.[ActivityDate], GETDATE()) / 3600.0 / 24.0 / 365.25 * 12
        WHEN @DurationInterval IN ('day', 'dd', 'd') THEN DATEDIFF(SECOND, UA.[ActivityDate], GETDATE()) / 3600.0 / 24.0
        WHEN @DurationInterval IN ('hour', 'hh') THEN DATEDIFF(SECOND, UA.[ActivityDate], GETDATE()) / 3600.0
        WHEN @DurationInterval IN ('minute', 'mi', 'n') THEN DATEDIFF(SECOND, UA.[ActivityDate], GETDATE()) / 60.0
        WHEN @DurationInterval IN ('second', 'ss', 's') THEN DATEDIFF(SECOND, UA.[ActivityDate], GETDATE())
    END < @DurationIncrement

下面是DATEADD查询。在此处粘贴计划。不幸的是,没有发生索引查找。这对我来说可能是一个错误的假设,但我很困惑为什么它根本没有发生。

DECLARE @UserId int = 1
DECLARE @ForTypeId int = 3
DECLARE @DurationInterval varchar(6) = 'hour'
DECLARE @DurationIncrement int = 1

SELECT
    COUNT(UA.[UserActivityId]) AS 'ActivityTypeCount'
FROM
    [dbo].[UserActivity] UA
WHERE
    -- Exclude the @UserId and @ForTypeId predicates.
    -- UA.[UserId] = @UserId
    -- AND UA.[ActivityTypeId] = @ForTypeId
    -- AND 
    (
        (@DurationInterval IN ('year', 'yy', 'yyyy') AND UA.[ActivityDate] > CONVERT(datetime2(0), DATEADD(YEAR, -@DurationIncrement, GETDATE())))
        OR
        (@DurationInterval IN ('month', 'mm', 'm') AND UA.[ActivityDate] > CONVERT(datetime2(0), DATEADD(MONTH, -@DurationIncrement, GETDATE())))
        OR
        (@DurationInterval IN ('day', 'dd', 'd') AND UA.[ActivityDate] > CONVERT(datetime2(0), DATEADD(DAY, -@DurationIncrement, GETDATE())))
        OR
        (@DurationInterval IN ('hour', 'hh') AND UA.[ActivityDate] > CONVERT(datetime2(0), DATEADD(HOUR, -@DurationIncrement, GETDATE())))
        OR
        (@DurationInterval IN ('minute', 'mi', 'n') AND UA.[ActivityDate] > CONVERT(datetime2(0), DATEADD(MINUTE, -@DurationIncrement, GETDATE())))
        OR
        (@DurationInterval IN ('second', 'ss', 's') AND UA.[ActivityDate] > CONVERT(datetime2(0), DATEADD(SECOND, -@DurationIncrement, GETDATE())))
        )

这是什么原因?我看到的行为是否是我使用OR否定它甚至可以使用索引的任何可能性的结果?我是否忽略了这里非常明显的东西?

更新:我上面的第二个问题导致我在OR操作之前执行查询。查询执行了索引查找,因此在这些比较过程中发生了 SQL Server 不喜欢的事情。在此处粘贴计划。

DECLARE @DurationIncrement int = 1

SELECT
    COUNT(UA.[UserActivityId]) AS 'ActivityTypeCount'
FROM
    [dbo].[UserActivity] UA
WHERE
    UA.[ActivityDate] > CONVERT(datetime2(0), DATEADD(HOUR, -@DurationIncrement, GETDATE()))

更新: 解决方案在这里共享。

sql-server index
  • 4 个回答
  • 908 Views
Martin Hope
PicoDeGallo
Asked: 2018-03-20 06:40:40 +0800 CST

具有聚集索引的表按唯一非聚集索引隐式排序

  • 4

我有一个表,用于捕获用户正在运行的主机平台。该表的定义很简单:

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

它存储的数据是基于使用来自浏览器的信息的 JavaScript 方法枚举的(我知道的不多,但如果需要可以找到):

平台

但是,当我在SELECT没有显式的情况下执行基本ORDER BY操作时,执行计划显示它正在使用UNIQUE NONCLUSTERED索引而不是索引来进行排序CLUSTERED。

SELECT * FROM [Auth].[ActivityPlatform] 

非集群缓存

当显式指定 时ORDER BY,它会正确排序ActivityPlatformId。

SELECT * FROM [Auth].[ActivityPlatform] ORDER BY [ActivityPlatformId]

集群缓存

DBCC SHOWCONTIG('[Auth].[ActivityPlatform]') WITH ALL_LEVELS, TABLERESULTS显示没有表碎片。

我错过了什么可能导致这个?我一直认为该表是在聚集索引上创建的,它应该自动隐式排序而不需要指定ORDER BY。SQL Server选择UQ的偏好是什么?在创建表格时我需要指定什么吗?

sql-server index
  • 1 个回答
  • 1353 Views
Martin Hope
PicoDeGallo
Asked: 2018-02-27 15:20:07 +0800 CST

利用触发器动态改变分区函数

  • 1

我想利用基于 a 的分区[TenantId](稍后结合日期范围)。PARTITION FUNCTION我不需要TRIGGER AFTER INSERT在. [TenantId]_ ALTER PARTITION FUNCTION_ SPLIT RANGE但是,我遇到了一个意外错误:

无法在/使用表“租户”上执行 ALTER PARTITION FUNCTION,因为该表是目标表或当前正在执行的触发器的级联操作的一部分。

首先,我正在创建PARTITION FUNCTION [PF_Tenant_Isolation]andPARTITION 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

在此之后,我将[Tenant]针对新创建的分区方案创建表。

IF OBJECT_ID('[Auth].[Tenant]', 'U') IS NULL
BEGIN
    CREATE TABLE [Auth].[Tenant] (
        [TenantId] [int] IDENTITY(1,1)
        ,[TenantActive] [bit] NOT NULL CONSTRAINT [DF_Tenant_TenantActive] DEFAULT 1
        ,[TenantName] [varchar](256) NOT NULL
        ,CONSTRAINT [PK_Tenant_TenantId] PRIMARY KEY CLUSTERED ([TenantId] ASC)
    ) ON [PS_Tenant_Isolation]([TenantId]);
END

我在创建触发器之前播种了第一个值。

INSERT INTO [Auth].[Tenant]
VALUES (1,'Partition Trigger Test A');

我针对 [Tenant] 表创建触发器。

CREATE TRIGGER [TR_Tenant_Isolation] ON [Auth].[Tenant]
AFTER INSERT
AS
BEGIN
    DECLARE @MaxInsertedId int
    SET @MaxInsertedId = (SELECT MAX([TenantId]) FROM inserted)

    ALTER PARTITION SCHEME [PS_Tenant_Isolation]
        NEXT USED [Auth];

    ALTER PARTITION FUNCTION [PF_Tenant_Isolation]()
        SPLIT RANGE (@MaxInsertedId);
END

我继续尝试插入第二个[Tenant]值。

INSERT INTO [Auth].[Tenant]
VALUES (1,'Partition Trigger Test B');

这是弹出上述错误的时候。基于错误本身以及阅读Technet 论点,我理解使用中的问题AFTER INSERT。由于事务的分区动作依赖于利用分区函数内的范围值,ALTER PARTITION SCHEME因此失败,因此整个事务也是如此。

AFTER 指定仅当触发 SQL 语句中指定的所有操作都已成功执行时才触发 DML 触发器。在触发此触发器之前,所有引用级联操作和约束检查也必须成功。

我已经研究过INSTEAD OF INSERT但没有任何成功。触发器触发一次并SPLIT RANGE使用值 0 更新 (从 NULL 隐式转换)。我相信这是由于IDENTITY没有在交易范围内正确捕获。

CREATE TRIGGER [TR_Tenant_Isolation] ON [Auth].[Tenant]
INSTEAD OF INSERT
AS
BEGIN
    DECLARE @MaxInsertedId int
    SET @MaxInsertedId =  (SELECT [TenantId] FROM inserted)

    ALTER PARTITION SCHEME [PS_Tenant_Isolation]
        NEXT USED [Auth];

    ALTER PARTITION FUNCTION [PF_Tenant_Isolation]()
        SPLIT RANGE (@MaxInsertedId);

    INSERT INTO [Auth].[Tenant] ([TenantActive], [TenantName])
    SELECT [TenantActive], [TenantName]
    FROM inserted;
END

[Tenant]由于尝试输入 0 (NULL),随后的行插入会产生额外的错误。

分区函数边界值列表中不允许有重复的范围边界值。添加的边界值已经存在于边界值列表的序号 1 中。

我该如何解决这个问题?我需要明确设置 的IDENTITY值[TenantId]吗INSTEAD OF INSERT?新插入[Tenant]将是相当零星的和最小的,但[TenantId]将成为其他表的约束键。这就是为什么我决定研究这种实现方法以便动态改变分区函数的原因。

sql-server database-design
  • 1 个回答
  • 2377 Views
Martin Hope
PicoDeGallo
Asked: 2018-02-23 06:47:19 +0800 CST

与复合主键配对时的单个或多个非聚集索引

  • 1

我有一个数据库,我在其中使用TenantId需要唯一标识特定租户的所有表,并且由于复合键中的排序要求,我TenantId在索引列表中排在第一位。现在有一个问题,Authentication其中User表包含TenantId, UserId(IDENTITY列)以及Email其他特定于登录的项目。

登录门户不是特定于租户的,因此在登录时,用户只需输入他们的Email,从而查找验证其登录信息的行。在这种情况下,我们无法立即利用 和 的复合主键,TenantId直到UserId找到适用于 的行Email。

TenantId和上的复合主键UserId将始终在所有其他条件子句中使用。但是,为了首先利用此键,我们必须首先根据 的查询查找该行Email。如果没有索引Email,将改为进行表扫描。

我的问题是,哪种类型的指数组合最适合这种情况?单独的单个非聚集索引Email,另一个复合键UserId以及与其他相关数据上的 INCLUDESEmail结合的单个非聚集索引,或者以上都不是?Email

该架构类似于:

CREATE TABLE [User] (
     [TenantId] [int] NOT NULL
    ,[UserId] [int] IDENTITY(1,1) NOT NULL
    ,[Email] [varchar](64) NOT NULL
    ,[FirstName] [varchar](32) NOT NULL
    ,[MiddleName] [varchar](32) NULL
    ,[LastName] [varchar](32) NOT NULL
    ,[PasswordHash] [varbinary](64) NOT NULL
    ,[PasswordSalt] [varbinary](32) NOT NULL
    ,[HashMethodId] [tinyint] NOT NULL
    ,[IsActive] [bit] NOT NULL CONSTRAINT [DF_User_IsActive] DEFAULT 1
    ,[IsLocked] [bit] NOT NULL CONSTRAINT [DF_User_IsLocked] DEFAULT 0

    ,CONSTRAINT [PK_User_TenantId_UserId] PRIMARY KEY CLUSTERED ([TenantId] ASC, [UserId] ASC)
    ,INDEX [IX_User_UserId_Email] NONCLUSTERED ([UserId] ASC, [Email] ASC)
    ,CONSTRAINT [FK_Tenant_TenantId] FOREIGN KEY ([TenantId]) REFERENCES [Tenant]([TenantId])
    ,CONSTRAINT [FK_HashMethod_HashMethodId] FOREIGN KEY ([HashMethodId]) REFERENCES [HashMethod]([HashMethodId])
);
CREATE NONCLUSTERED INDEX [IX_User_Email] ON [User]([Email]) INCLUDE ([PasswordHash],[PasswordSalt],[HashMethodId],[IsActive],[IsLocked])

-- Note for research: Why can an index that has INCLUDE not be specified in CREATE TABLE?

我的理解是,[IX_User_UserId_Email]在这种情况下,快速绑定回 很有用[PK_User_TenantId_UserId],从而更有效地寻求适当的隔离级别。这是一个错误的假设吗?我使用 just 会更好[IX_User_Email]吗?

  • 所有表都将 JOIN 到UseronTenantId和UserId。
  • 没有表会严格 JOIN 到User基于UserId.
  • 将严格根据 的查询进行查找Email。TenantId并且UserId在获取该行之前不会知道。获取行后,其余查询将使用TenantIdand UserId。

我一直在考虑的另一个选项是在Tenant表中,包括一个Domain指定租户源电子邮件域的列(在租户中始终相同)。一旦用户在登录页面上输入他们的Email选项卡/选择Password字段,它将解析出电子邮件域 ( @sample.com),允许我们查询较小的Tenant表以找到他们的TenantId,从而能够利用复合键[PK_User_TenantId_UserId],从而只需要在Email. 然而,这可能是一种不必要的方法。

sql-server database-design
  • 3 个回答
  • 733 Views
Martin Hope
PicoDeGallo
Asked: 2017-12-06 13:01:39 +0800 CST

SQL Server 2016 ISNULL 返回 1900-01-01

  • 3

我有一个datetime2名为的列DocDate,我正在尝试评估一个ISNULL检查以返回一个空白''值而不是NULL.

声明的片段:

SELECT TOP 100
    DocumentId
    ,DocDate
    ,ISNULL(DocDate,'') AS 'DocDateEmpty'
FROM
    DocDetails
WHERE
    DocDate IS NULL

这将返回:1900-01-01 00:00:00.0000000

我的WHERE子句清楚地只带回显式的行NULL,因此它不是DocDate一个空字符串并评估为的问题0。

SSMS 捕获

如何DocDate IS NULL正确评估但ISNULL失败?

根据MSDN,ISNULL应该正确评估文字 NULL值并返回一个空值。

返回与check_expression相同的类型。如果提供文字 NULL 作为check_expression,则返回replacement_value的数据类型。如果提供了文字 NULL 作为check_expression并且没有提供replacement_value,则返回一个int。

sql-server t-sql
  • 1 个回答
  • 5943 Views
Martin Hope
PicoDeGallo
Asked: 2017-04-05 11:07:07 +0800 CST

CPU 时钟速度与 CPU 核心数 - 更高的 GHz,还是 SQL Server 的更多核心?

  • 36

我们开始为 VMware 中的 SQL Server 2016 节点虚拟集群配置一组物理服务器。我们将使用企业版许可证。

我们计划设置 6 个节点,但对于在 CPU 时钟速度与 CPU 核心数方面配置物理服务器的理想方式存在一些争议。

我知道这在很大程度上取决于事务量和存储的数据库数量以及其他特定于软件的因素,但是是否有建议的一般经验法则?

例如,双 8 核 3.2 GHz 物理服务器(16 核)是否比双 16 核 2.6 GHz 服务器(32 核)更优惠?

有没有人遇到过进一步深入研究此类主题的白皮书?

sql-server performance
  • 4 个回答
  • 25316 Views
Martin Hope
PicoDeGallo
Asked: 2017-02-23 16:17:56 +0800 CST

抑制特定的 SQL Server 日志警告和消息

  • 4

我想尽量减少 SQL Server 2012 日志中某些警告和消息的输出,例如当 spid 被终止时。我无法找到有关抑制/扩展哪些消息实际发送到错误日志的信息。这是通过跟踪标志完成的吗?

我正在尝试减少我们的开发数据库服务器上的警告数量,并将其限制为合法错误。我们有开发人员在同一台服务器上的多个数据库中杀死 spid 或刷新查询缓存以进行性能调整(使用索引调整、强制有意的表争用、创建死锁等)。让日志文件充满这些警告只是一种烦恼,我想看看是否可以抑制。

sql-server logging
  • 1 个回答
  • 1192 Views
Martin Hope
PicoDeGallo
Asked: 2016-08-24 12:12:59 +0800 CST

按 MB 而不是百分比的自动增长

  • 1

在深入研究 Autogrowth 和围绕它的最佳实践(主要是主动并提前调整文件组大小)之后,有一个迫在眉睫的问题,我似乎没有找到一个彻底的答案。大多数文章,包括 TechNet,总是提到将 Autogrowth 设置为 10-15% 作为故障保险的做法。似乎很少提及将 MB 增长选项用作故障保险。

例如,假设您当前的数据库大小为 500GB,文件增长大约为每天约 1GB,给或取几百 MB。每个周末,您将必要的文件组调整 X 数量以应对增长——比如将其提高到 540GB 以应对近一个月的增长。如果在达到 540GB 后您无法对其进行调整(只是忘记了,意外的表扩展等),MSSQL 将开始行动并尝试将数据库增长 15%,但由于增长量而导致持续超时太大,服务器无法自动处理。这会导致应用程序超时,因此无论如何都需要手动干预。

我提出这个是因为在测试中,Autogrowth by percent 似乎在这些测试用例中提供了超时。但是,如果我将 Autogrowth 设置为一组 MB,例如 1,000MB,它会毫无问题地增长并且会及时增长。

所以总结一下我的问题,为什么文章(至少我读过的文章)会注意在没有发生主动手动文件增长的情况下使用按百分比自动增长而不是按 MB 自动增长的做法?在我看来,在测试和理论上,您更希望 Autogrow 调整设定的 MB 量。

我的这种想法是错误的,还是我只是读错了东西?很高兴听到你们在这里使用什么类型的管理技术。

谢谢!

sql-server sql-server-2012
  • 1 个回答
  • 2705 Views
Martin Hope
PicoDeGallo
Asked: 2015-11-24 18:09:34 +0800 CST

使用多个分隔符提取数据?

  • 3

我有一个由分号和逗号分隔的旧数据源列。第一个分号表示姓氏,第二个表示名字和中间名(或首字母),最后一个分号表示个人类型。逗号表示新名称已开始。这是此数据的示例。

+-------+---------------------------------------------------------------------------------------------------------------------+
|  ID   | SOURCE                                                                                                              |
+-------+---------------------------------------------------------------------------------------------------------------------+
| 62963 | RENZ;MICHAEL;DECEASED,WANDER;MARIA;MINOR,WANDER;HENRY RUDOLPH;MINOR,WANDER;ROSA;MINOR,WANDER;PAUL EMIL;MINOR        |
| 62964 | HERNDON;A C;ESTATE,BERRING;A F;DECEASED,BEIRING;A F;DECEASED,BEIRING;ANDREAS FREDERICK;DECEASED                     |
| 62965 | ZINCH;;ESTATE,ZINTZ;;ESTATE,HAYNES;HENRY;DECEASED                                                                   |
| 62965 | ZINCH;;ESTATE,ZINTZ;;ESTATE,HAYNES;HENRY;DECEASED                                                                   |
| 62966 | KRAUS;JOSEPHINE;MINOR,KENNEDY;GEORGE;DECEASED                                                                       |
| 62967 | CAREY;JAMES;ESTATE,DE LA GARZA;REFUGIO;DECEASED                                                                     |
| 62968 | LEWIS;FLORENCE;ESTATE,LOCKWOOD;ALBERT A;DECEASED                                                                    |
| 62969 | GLAESER;EMMA;MINOR,GLAESER;HERMAN JR;MINOR,GLAESER;HERMAN;MINOR,RODRIGUEZ;HILARIO;DECEASED,RODRIGUEZ;MARIE;DECEASED |
| 62970 | STORY;BETTIE;ESTATE,EIGENDORFF;FRANZ;DECEASED                                                                       |
| 62971 | HOWELL;MAMIE;MINOR,HOWELL;ETHEL;MINOR                                                                               |
+-------+---------------------------------------------------------------------------------------------------------------------+

我试图以这样的方式提取数据,以便它可以适应不同的模式:

+-----------+------------+-------------+-------------------+----------+
|      ID   |   SEQUENCE |    LAST     |    FIRSTMIDDLE    |   TYPE   |
+-----------+------------+-------------+-------------------+----------+
|     62963 |          1 | RENZ        | MICHAEL           | DECEASED |
|     62963 |          2 | WANDER      | MARIA             | MINOR    |
|     62963 |          3 | WANDER      | HENRY RUDOLPH     | MINOR    |
|     62963 |          4 | WANDER      | ROSA              | MINOR    |
|     62963 |          5 | WANDER      | PAUL EMIL         | MINOR    |
|     62964 |          1 | HERNDON     | A C               | ESTATE   |
|     62964 |          2 | BERRING     | A F               | DECEASED |
|     62964 |          3 | BEIRING     | A F               | DECEASED |
|     62964 |          4 | BEIRING     | ANDREAS FREDERICK | DECEASED |
|     62965 |          1 | ZINCH       |                   | ESTATE   |
|     62965 |          2 | ZINTZ       |                   | ESTATE   |
|     62965 |          3 | HAYNES      | HENRY             | DECEASED |
|     62966 |          1 | KRAUS       | JOSEPHINE         | MINOR    |
|     62966 |          2 | KENNEDY     | GEORGE            | DECEASED |
|     62967 |          1 | CAREY       | JAMES             | ESTATE   |
|     62967 |          2 | DE LA GARZA | REFUGIO           | DECEASED |
|     62968 |          1 | LEWIS       | FLORENCE          | ESTATE   |
|     62968 |          2 | LOCKWOOD    | ALBERT A          | DECEASED |
|     62969 |          1 | GLAESER     | EMMA              | MINOR    |
|     62969 |          2 | GLAESER     | HERMAN JR         | MINOR    |
|     62969 |          3 | GLAESER     | HERMAN            | MINOR    |
|     62969 |          4 | RODRIGUEZ   | HILARIO           | DECEASED |
|     62969 |          5 | RODRIGUEZ   | MARIE             | DECEASED |
|     62970 |          1 | STORY       | BETTIE            | ESTATE   |
|     62970 |          2 | EIGENDORFF  | FRANZ             | DECEASED |
|     62971 |          1 | HOWELL      | MAMIE             | MINOR    |
|     62971 |          2 | HOWELL      | ETHEL             | MINOR    |
+-----------+------------+-------------+-------------------+----------+

这种类型的数据提取是我不太熟悉的。我想我需要使用 和 的复杂组合SUBSTRING,CHARINDEX但鉴于源列可以包含的条目数量各不相同,我不确定如何最好地解决这个问题。任何关于我应该从哪里开始的指导都会非常有帮助。

sql-server t-sql
  • 2 个回答
  • 2960 Views
Martin Hope
PicoDeGallo
Asked: 2015-10-02 12:46:16 +0800 CST

每周完整备份和每日差异备份,保存每周的完整备份?

  • 3

我想创建一个维护计划,执行每周日早上完成的完整备份。周一到周五下班后,我想根据这个完整备份执行差异备份。但是,我不想覆盖前一周的完整备份,而是希望为历史记录/异地保留该完整备份,同时消除与该完整备份相关的差异。我计划创建的计划类型如下:

  • 如果需要,可以从周日凌晨开始重建数据库索引。
    • 对此的进一步警告是根据存在的碎片量重新组织+更新统计信息。
  • 在索引维护之后,在同一天早上创建了一个完整备份。
  • 周一到周五晚上,基于完整备份进行差异备份。
  • 在差异之后,运行数据库完整性检查。
  • 下周日到来,建立完整备份,删除前一周的差异,并将之前的完整备份在本地带到 Drobo 下班后。

这种计划的原因是由于我正在使用的 Azure 环境的 HDD 大小限制。鉴于此,这是一个合理的策略,还是我应该在哪里寻求改进?其次,我如何去保留前一周的完整数据库备份而不是差异?到目前为止,我阅读的文章似乎表明,这种性质的循环备份将同时删除完整备份和差异。

这是 Azure 环境中 Windows Server 2012 VM 上的 SQL Server 2012 实例。有 5 个数据库,每个数据库从 6GB 到 10GB,都会受到此类计划的影响。

感谢你的协助。

sql-server backup
  • 1 个回答
  • 2749 Views
Martin Hope
PicoDeGallo
Asked: 2015-06-02 07:56:09 +0800 CST

RIGHT() 函数返回空白结果

  • 1

我有一个列包含我需要拆分成三个单独列的信息。我目前有一个部分工作的 SELECT 语句,但我的 ChangeTo 列没有返回任何数据,我无法理解为什么。这是当前返回的列的样子:

| bp_comment                                             |
----------------------------------------------------------
| changed status from "new" to "in progress"             |
| changed ORT status from "in progress" to "Code Review" |
| changed MileStone from "1.1" to "1.2"                  |

以下是我需要返回结果的方式:

| ChangeType              |  ChangeFrom  |   ChangeTo  |
-----------------------------------------------------
| changed status from     | new          | in progress |
| changed ORT status from | in progress  | Code Review |
| changed MileStone from  | 1.1          | 1.2         |

以下是现在返回结果的方式:

| ChangeType              |  ChangeFrom  |   ChangeTo  |
-----------------------------------------------------
| changed status from     | new          |             |
| changed ORT status from | in progress  |             |
| changed MileStone from  | 1.1          |             |

这是我正在使用的查询:

SELECT
    LEFT(CONVERT(VARCHAR(MAX), bp.bp_comment), CHARINDEX(' from ', CONVERT(VARCHAR(MAX), bp.bp_comment)) + 5) AS 'ChangeType'
    ,REPLACE(SUBSTRING(CONVERT(VARCHAR(MAX), bp.bp_comment), CHARINDEX(' from ', CONVERT(VARCHAR(MAX), bp.bp_comment)) + 5, CHARINDEX(' to ', CONVERT(VARCHAR(MAX), bp.bp_comment)) - CHARINDEX(' from ', CONVERT(VARCHAR(MAX), bp.bp_comment)) - 5), '"', '') AS 'ChangeFrom'
    ,REPLACE(RIGHT(CONVERT(VARCHAR(MAX), bp.bp_comment), CHARINDEX(' to ', REVERSE(CONVERT(VARCHAR(MAX), bp.bp_comment)))), '"', '') AS 'ChangeTo'
FROM
    bug_posts bp

先感谢您!

sql-server
  • 2 个回答
  • 962 Views

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve