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
    • 最新
    • 标签
主页 / dba / 问题 / 218641
Accepted
Erik Darling
Erik Darling
Asked: 2018-09-27 08:42:29 +0800 CST2018-09-27 08:42:29 +0800 CST 2018-09-27 08:42:29 +0800 CST

为什么 SQL Server 在 DMV 或查询计划中没有任何缺失的索引请求?

  • 772

我有一个 SQL Server 数据库,其中的查询非常慢,并且有很多锁定和阻塞。

当我查看缺少的索引 DMV 和查询计划时,没有任何建议。

这是为什么?

sql-server performance
  • 1 1 个回答
  • 1702 Views

1 个回答

  • Voted
  1. Best Answer
    Erik Darling
    2018-09-27T08:42:29+08:002018-09-27T08:42:29+08:00

    您可能没有丢失索引请求的原因有很多!

    我们将更详细地了解其中的一些原因,并讨论该功能的一些一般限制。

    一般限制

    首先,来自:缺失索引功能的限制:

    • 它没有指定要在索引中使用的列的顺序。

    如本问答中所述:SQL Server 如何确定缺失索引请求中的键列顺序?,索引定义中的列顺序由 Equality vs Inequality 谓词决定,然后是表中的列序号位置。

    选择性没有猜测,可能有更好的顺序可用。弄清楚这一点是你的工作。

    特殊索引

    缺失的索引请求也不涵盖“特殊”索引,例如:

    • 集群的
    • 过滤
    • 分区
    • 压缩
    • XML 编辑
    • 空间化
    • 列存储-d
    • 索引浏览

    考虑哪些列?

    缺少索引键列是从用于过滤结果的列生成的,例如:

    • 加入
    • WHERE 子句

    Missing Index Included 列是从查询所需的列生成的,例如:

    • 选择
    • 通过...分组
    • 订购方式

    即使经常,您排序或分组依据的列也可以作为关键列有益。这又回到了限制之一:

    • 它不是为了微调索引配置。

    例如,此查询不会注册丢失的索引请求,即使在 LastAccessDate 上添加索引会阻止排序(并溢出到磁盘)的需要。

    SELECT TOP (1000) u.DisplayName
    FROM dbo.Users AS u
    ORDER BY u.LastAccessDate DESC;
    

    坚果

    此分组查询也不针对位置。

    SELECT TOP (20000) u.Location
    FROM dbo.Users AS u
    GROUP BY u.Location
    

    坚果

    这听起来不是很有帮助!

    嗯,是的,但总比没有好。把丢失的索引请求想象成一个哭闹的婴儿。你知道有问题,但作为一个成年人,你要弄清楚那个问题是什么。

    你还没有告诉我为什么我没有它们,虽然...

    放松,巴科。我们快到了。

    跟踪标志

    如果启用TF 2330,则不会记录丢失的索引请求。要确定您是否启用了此功能,请运行以下命令:

    DBCC TRACESTATUS;
    

    索引重建

    重建索引将清除丢失的索引请求。因此,在您开始 Hi-Ho-Silver-Away 重建每个索引之前,一旦有少量碎片潜入,请考虑每次执行此操作时要清除的信息。

    您可能还想考虑为什么对索引进行碎片整理没有帮助。除非您使用的是Columnstore。

    添加、删除或禁用索引

    添加、删除或禁用索引将清除该表的所有缺失索引请求。如果您正在处理同一张表上的多个索引更改,请确保在进行任何更改之前将它们全部编写出来。

    琐碎的计划

    如果计划足够简单,索引访问选择足够明显,成本足够低,那么您将得到一个简单的计划。

    这实际上意味着优化器无需做出基于成本的决策。

    通过保罗怀特:

    哪些类型的查询可以从 Trivial Plan 中受益的细节经常变化,但连接、子查询和不等式谓词通常会阻止这种优化。

    当计划微不足道时,不会探索其他优化阶段,也不会请求丢失的索引。

    查看这些查询及其计划之间的区别:

    SELECT *
    FROM dbo.Users AS u
    WHERE u.Reputation = 2;
    
    SELECT *
    FROM dbo.Users AS u
    WHERE u.Reputation = 2
    AND 1 = (SELECT 1);
    

    坚果

    第一个计划很简单,没有显示任何请求。在某些情况下,错误会阻止丢失的索引出现在查询计划中;不过,它们通常更可靠地记录在缺失的索引 DMV 中。

    SARGability

    即使使用索引,优化器也无法有效使用索引的谓词可能会阻止它们被记录。

    通常不是 SARGable 的事情是:

    • 包含在函数中的列
    • 列 + SomeValue = SomePredicate
    • Column + AnotherColumn = SomePredicate
    • 列 = @Variable 或 @Variable 为 NULL

    例子:

    SELECT *
    FROM dbo.Users AS u
    WHERE ISNULL(u.Age, 1000) > 1000;
    
    
    SELECT *
    FROM dbo.Users AS u
    WHERE DATEDIFF(DAY, u.CreationDate, u.LastAccessDate) > 5000
    
    
    SELECT *
    FROM dbo.Users AS u
    WHERE u.UpVotes + u.DownVotes > 10000000
    
    
    DECLARE @ThisWillHappenWithStoredProcedureParametersToo NVARCHAR(40) = N'Eggs McLaren'
    SELECT *
    FROM dbo.Users AS u
    WHERE u.DisplayName LIKE @ThisWillHappenWithStoredProcedureParametersToo 
          OR @ThisWillHappenWithStoredProcedureParametersToo IS NULL;
    

    这些查询都不会注册丢失的索引请求。有关这些的更多信息,请查看以下链接:

    • 可选参数和缺失索引请求
    • 两个日期列的 SARGable WHERE 子句
    • 在仅使用文字值的 WHERE 子句中替换 ISNULL() 有哪些不同的方法?

    你已经有一个好的索引

    拿这个指数:

    CREATE INDEX ix_whatever ON dbo.Posts(CreationDate, Score) INCLUDE(OwnerUserId);

    这个查询看起来不错:

    SELECT p.OwnerUserId, p.Score
    FROM dbo.Posts AS p
    WHERE p.CreationDate >= '20070101'
    AND   p.CreationDate < '20181231'
    AND   p.Score >= 25000
    AND 1 = (SELECT 1)
    ORDER BY p.Score DESC;
    

    该计划是一个简单的搜索...

    坚果

    但是因为前导键列是针对选择性较低的谓词,所以我们最终做的工作比我们应该做的要多:

    表“帖子”。扫描计数 13,逻辑读取 136890

    如果我们改变索引键列的顺序,我们做的工作就会少很多:

    CREATE INDEX ix_whatever ON dbo.Posts(Score, CreationDate) INCLUDE(OwnerUserId);

    坚果

    并且阅读量明显减少:

    表“帖子”。扫描计数 1,逻辑读取 5

    SQL Server 正在为您创建索引

    在某些情况下,SQL Server 将选择通过索引假脱机动态创建索引。当存在索引假脱机时,将不会出现丢失的索引请求。当然,自己添加索引可能是个好主意,但不要指望 SQL Server 会帮助您解决这个问题。

    坚果

    • 18

相关问题

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

  • 我在哪里可以找到mysql慢日志?

  • 如何优化大型数据库的 mysqldump?

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