小编Eri*_*ing的帖子

执行计划显示缺少索引但查询速度很快

在查看实际执行计划时,即使查询不到 1 秒,它也会显示缺少索引。

SELECT
    Account.AccountID,
    Account.Name
FROM
    account      
    LEFT OUTER JOIN accountfeaturesetting afs 
ON afs.accountid = account.accountid   
and afs.featureid = 'Schedules'
 and  
afs.settingid = 'EditReasons'           
WHERE
    ISNULL(afs.Value, '0') = '0'  
    AND EXISTS 
(SELECT 1 FROM program WHERE program.AccountID = account.AccountID
 AND program.Active = 1 
AND (program.ScheduleEditReasonFlags <> 0 
OR program.ScheduleEditReasonFields <> 0))
    AND account.IsMaster = 0
    AND account.BeginDate IS NOT NULL
Run Code Online (Sandbox Code Playgroud)

执行计划显示:

CREATE NONCLUSTERED INDEX [<Name of Missing Index, sysname,>]
ON [dbo].[Account] ([IsMaster],[BeginDate])
INCLUDE ([AccountID],[Name])
Run Code Online (Sandbox Code Playgroud)

即使查询只需要 1 秒,我们是否需要创建索引?应该在什么基础上创建索引?

我将把这个查询作为日常工作来运行。

index sql-server execution-plan

8
推荐指数
1
解决办法
842
查看次数

How can I resolve a database trigger's name with built-in functions?

I have a database trigger that I use to prevent me from creating certain procedures in user databases.

It appears in sys.triggers, with an object_id, but I can't use the object_id function to find it.

SELECT OBJECT_ID(t.name, t.type) AS object_id, *
FROM   sys.triggers AS t;
Run Code Online (Sandbox Code Playgroud)

坚果

Likewise, I can find it in sys.dm_exec_trigger_stats. I can't get object_name to resolve, but object_definition does.

SELECT OBJECT_NAME(dets.object_id, dets.database_id) AS object_name,
       OBJECT_DEFINITION(dets.object_id) AS object_definition,
       *
FROM   sys.dm_exec_trigger_stats AS dets;
Run Code Online (Sandbox Code Playgroud)

坚果

Is there a …

trigger sql-server metadata ddl-trigger

8
推荐指数
2
解决办法
466
查看次数

Ola Hallengren 索引维护 - 命令之间的时间长吗?

我在所有服务器上运行 Ola Hallengren 脚本以进行索引和统计维护。当我查看命令日志表时,我注意到命令结束和下一个命令开始之间的时间很长。有时这个间隔会超过一个小时。

有没有其他人在他们的系统上观察到这一点?我可以做些什么来缩短(我猜)要维护的项目之间的发现时间?下面是我运行它们的参数集。

sqlcmd -E -S $(ESCAPE_SQUOTE(SRVR)) -d master -Q "EXECUTE [dbo].[IndexOptimize] 
@Databases = 'USER_DATABASES', 
@LogToTable = 'Y',
@FragmentationLow = NULL,
@FragmentationMedium = 'INDEX_REORGANIZE,INDEX_REBUILD_ONLINE,INDEX_REBUILD_OFFLINE',
@FragmentationHigh = 'INDEX_REBUILD_ONLINE,INDEX_REBUILD_OFFLINE',
@FragmentationLevel1 = 50,
@FragmentationLevel2 = 80,
@UpdateStatistics = 'ALL',
@OnlyModifiedStatistics = 'Y' " -b
Run Code Online (Sandbox Code Playgroud)

所以当我运行这个时:

SELECT DATEDIFF(MINUTE, cl.StartTime, cl.EndTime)
, *
FROM master.dbo.CommandLog AS cl
WHERE cl.StartTime > '2014-12-13'
ORDER BY cl.ID
Run Code Online (Sandbox Code Playgroud)

我看到这个:

样本输出

sql-server maintenance ola-hallengren

7
推荐指数
2
解决办法
2070
查看次数

`sys.dm_os_wait_stats` 中的值是否会在达到最大值时重置为 0 或停止累积?

查看sys.dm_os_wait_stats 时,以下列定义为BIGINT

  • waiting_tasks_count
  • wait_time_ms
  • max_wait_time_ms

如果这些值中的任何一个超过9,223,372,036,854,775,807,计数器是否重置为 0,或者只是停止计数?

从表定义中不清楚幕后发生了什么:

sp_helptext 'sys.dm_os_wait_stats'
Run Code Online (Sandbox Code Playgroud)

返回:

CREATE VIEW sys.dm_os_wait_stats AS  
 SELECT *  
 FROM OpenRowset(TABLE SYSWAITSTATS)  
Run Code Online (Sandbox Code Playgroud)

所以这有点像一个黑匣子。

在某些 DMV 中,大量数字可能会变为负数。一个例子是 中的total_elapsed_timedm_exec_requests

sql-server dmv

7
推荐指数
1
解决办法
168
查看次数

SQL Server 中的日期数学是如何工作的?

我经常在子句中看到用DATEADD和编写的查询来定义一个范围,将日期时间展平为 0 小时,或者找到一个月或一年的最后一天,但我不明白所有部分是如何工作的。DATEDIFFWHERE

例如,这将查找从当天开始到 30 天前一天开始的日期。

SELECT *
FROM tbl
WHERE datecol >= DATEADD(DAY, DATEDIFF(DAY, 0, GETUTCDATE()), 0)
AND datecol   <  DATEADD(DAY, DATEDIFF(DAY, 0, GETUTCDATE()), -30);
Run Code Online (Sandbox Code Playgroud)

这的所有不同部分都完成了什么?

sql-server date-math

7
推荐指数
1
解决办法
2683
查看次数

强制 SQL Server 使用碎片索引?

我有一个非常大的表(> 10M 行),经常进行 crud 操作。它有适当的索引,但它们很快就会碎片化。如果没有定期的索引重组/重建维护计划,索引碎片很容易超过 90%。

现在我已经通过每天重新组织索引和每周重建来解决这个问题。我还使用了填充因子等来降低碎片化。

我的主要问题是,当索引过于分散时,SQL Server 会忽略索引并执行全表扫描。当这种情况发生时,它几乎杀死了应用程序,因为重复扫描如此大的表真的很繁重。我很确定在这些情况下使用碎片索引会更快。

有没有办法让 SQL Server 使用索引而不管它的碎片如何?

performance index sql-server index-tuning sql-server-2017

7
推荐指数
1
解决办法
460
查看次数

已提交读隔离下的缺失行

众所周知,Read Committed 隔离容易出现不同的异常。我阅读了伟大的保罗怀特关于隔离级别的系列。与讨论相关的帖子是这个:

它声明(再次,这是众所周知的),在读提交隔离下运行的语句:

Can encounter the same row multiple times;
Can miss some rows completely;
Run Code Online (Sandbox Code Playgroud)

我的问题是关于“缺失行”部分。讨论缺失行的示例通常使用以下查询来演示问题:

select count(*) from table.

我的问题是在“常规”选择查询中可以遗漏行吗?意思是,可以像这样的查询

select * from table

甚至

select * from table where id = @id

还会错过在该查询开始之前提交的行吗?此问题仅适用于使用锁定(而非 RCSI)提交的读取,因为 RCSI 不允许这些类型的异常。

sql-server concurrency isolation-level

7
推荐指数
1
解决办法
234
查看次数

将 5.6 升级到 5.7 不会丢失任何数据

我想将 MySQL 从 5.6 升级到 5.7,但我已经有了现有的数据库和表。我应该如何升级而不丢失任何数据?

mysql-5.6

6
推荐指数
1
解决办法
3万
查看次数

文本列比较等于 where 子句但不选择匹配行

我们在查询生产数据库中的表时遇到问题。一个文本列将与我们在 where 子句中过滤的字符串相等,但 postgres 不会选择该行。(我们在 postgres 11.11 上)我们的表设置如下:

(PROD)=> \d names;
                           Table "public.names"
        Column        |            Type             | Collation | Nullable | Default
----------------------+-----------------------------+-----------+----------+---------
 name                 | text                        |           | not null |
 processed_name       | text                        |           | not null |
 name_index           | integer                     |           | not null |
 when_created         | timestamp without time zone |           | not null |
Indexes:
    "names_pkey" PRIMARY KEY, btree (name, processed_name)
    "names_name_index_key" UNIQUE CONSTRAINT, btree (name_index)
    "ix_names_name" btree (name)
    "ix_names_processed_name" btree (processed_name)
Run Code Online (Sandbox Code Playgroud)

当我们处理名称列表时,我们会检查它们是否已经在表中,以防止重复添加和违反主键约束。

然而,在一个名字上,'?????? ????????? ???????',查看名称是否已经存在的查询返回一个空集, …

postgresql string

6
推荐指数
1
解决办法
67
查看次数

后悔身份:有没有办法强制插入指定身份列?

为了防止XY 问题,这是我们要解决的实际问题:

问题:

不幸的是,我们有一堆查找表,它们是在主键上使用标识列创建的,这是一个int. 我们希望可以简单地删除身份,但是,我们有一些带有指向身份列的外键的大型表,我的理解是在这种情况下删除身份很困难。我们对身份感到遗憾的原因是因为这些表需要跨多个环境同步,而开发人员通过编写脚本将数据插入到这些表中,而我们在多个环境上运行这些脚本但不一定总是按照相同的顺序,所以我们问开发人员始终:

  1. 启用身份插入
  2. 插入具有硬编码整数 ID 的行
  3. 禁用身份插入

如果每个人都这样做,数据要么保持同步,要么脚本失败,我们可以立即采取纠正措施来解决冲突。当然,有时开发者忘记遵守规则,直接无标识地插入,不同环境下以不同顺序运行的不同脚本的自动增量导致它们不同步,从而出现问题。

一个想法:

我们可以强制开发人员始终指定标识列吗?我认为没有办法简单地禁用这些表上的身份。如果我们将身份重新播种到较低的数字会怎样?当种子值已经存在时,任何未指定所有列的插入都会失败,并且会继续失败,直到插入尝试的次数超过现有(连续)行的数量。但是,在一次正确的插入之后,就会重新为表设定种子,下一次不正确的插入将再次使用自动增量。因此,这个想法的推断是在每次插入后(也许使用触发器,这感觉很奇怪,但可能有效?),或者按计划,或者可能每次我们运行开发人员的脚本时,将表重新设置为一个较低的现有数字。

这是一个合理的想法,和/或有更好的解决方案吗?

旁注:我们确实有一些其他想法,我认为这些想法超出了这个问题的范围,例如:

  1. 门控签入将解析脚本以插入某些表而不指定标识列,如果我们检测到这一点,则会失败。
  2. 将所有这些数据存储在源中并在部署时更新整个表。(而不是使用运行一次插入脚本。)
  3. 不要运行在所有环境上更改这些表的数据脚本,而是使用复制或其他同步机制。

尽管从长远来看,这些其他想法可能会更好,但似乎最容易实现的目标只是重新播种这些表,因此不正确的插入将会失败。

sql-server identity sql-server-2017

6
推荐指数
2
解决办法
1420
查看次数