代码之家  ›  专栏  ›  技术社区  ›  Abe Miessler

如何提高聚集索引查找的性能

  •  26
  • Abe Miessler  · 技术社区  · 15 年前

    我正在尝试提高运行非常缓慢的查询的性能。在经历了 实际执行计划 我发现 聚集索引查找 占82%。我有什么方法可以提高 索引查找 ?下面是问题的图像 索引查找 来自执行计划以及它正在使用的索引和表。

    alt text http://img340.imageshack.us/img340/1346/seek.png

    索引:

    /****** Object:  Index [IX_Stu]    Script Date: 12/28/2009 11:11:43 ******/
    CREATE CLUSTERED INDEX [IX_Stu] ON [dbo].[stu] 
    (
     [StuKey] ASC
    )WITH (PAD_INDEX  = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY]
    

    表(为简洁起见省略了一些列):

    CREATE TABLE [dbo].[stu](
     [StuCertKey] [int] IDENTITY(1,1) NOT NULL,
     [StuKey] [int] NULL
     CONSTRAINT [PK_Stu] PRIMARY KEY NONCLUSTERED 
    (
     [StuCertKey] ASC
    )WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF, FILLFACTOR = 80) ON [PRIMARY]
    ) ON [PRIMARY]
    
    9 回复  |  直到 7 年前
        1
  •  21
  •   Aaronaught    15 年前

    我在这里概括一下,但是…

    在大多数情况下,聚集索引查找是最佳情况。我能想到的提高绩效的唯一方法是:

    • 如果可能,更新查询以返回较少的行/列;
    • 整理或重建索引;
    • 跨多个磁盘/服务器分区索引。

    如果它只返回138行,而且速度很慢…也许它被其他进程阻塞了?您是单独测试,还是同时在线测试其他用户/流程?或者可能是硬件问题,比如磁盘故障。

        2
  •  12
  •   StrayCatDBA    12 年前

    使用非聚集索引时会出现聚集索引查找,而且不一定是坏的。

    考虑以下查询:

    SELECT s.StuKey, s.Name, s.Address, s.City, s.State FROM stu s WHERE State='TX'
    

    如果stukey上只有聚集索引,那么SQL Server只有1个选项,它必须扫描整个表,查找state=“tx”所在的行并返回这些行。

    如果在状态中添加非聚集索引

    CREATE INDEX IX_Stu_State on Stu (State)
    

    现在,SQL Server有了一个新选项。它可以选择使用非聚集索引进行查找,这将产生state='tx'的行。但是,为了在select中返回剩余的列,它必须通过对每一行执行聚集索引查找来查找这些列。

    如果希望减少聚集索引查找,那么可以通过在索引中包含额外的列来使索引“覆盖”。

     CREATE INDEX IX_Stu_State2 on Stu (State) INCLUDE (name, address, city )
    

    此索引现在包含回答上述查询所需的所有列。查询将执行索引查找以仅返回状态为“tx”的行,并且可以从非聚集索引中提取其他列,因此聚集索引查找将消失。

        3
  •  7
  •   Tom H zenazn    15 年前

    返回138行的聚集索引范围查找不是您的问题。

    从技术上讲,您可以通过缩小聚集索引来提高寻道性能:

    两者都会对测距时间产生相当大的影响,因为它们减少了IO,并且需要进行物理读取。当然,和通常一样,结果会因大量其他因素而变化,例如您要投影哪些列(将投影列逐出到BLOB分配单元中实际上可能会对某些查询产生不利影响)。作为旁注,通常碎片对这种短程扫描的影响不大。这还要看情况而定。

    但正如我所说,我高度怀疑这是你真正的问题。您只发布了计划的选定部分和自己分析的结果。真正的根本原因可能完全在其他地方。

        4
  •  3
  •   gbn    15 年前

    思想。。。

    • 为什么ix_stu集群?在内部,SQL Server向非唯一聚集索引添加了一个4字节的“uniqueifier”。理由是什么?这也会使你的pk膨胀。

    • 您正在运行的实际查询是什么?

    • 最后,为什么填充因子80%?

    编辑:

    • “正常”填充因子为90%,但这只是一个经验法则。

    • 一个11连接查询?这很可能是你的问题。你的连接是什么,何处子句等?什么是全文计划?

        5
  •  1
  •   Pedro    15 年前

    你试过维护这个索引吗?喜欢整理吗?它的价格如此之高(120.381),似乎真的很奇怪。索引查找是最快的索引操作,不应该花那么长时间。你能过账吗?

        6
  •  1
  •   kdgregory    15 年前

    一些一般性的建议:当我必须进行查询优化时,我首先要写出我认为执行计划应该是什么。

    一旦我决定了我认为执行计划应该是什么,我就尝试使实际的查询适合这个计划。对于每个DBMS,实现这一点的技术是不同的,不一定从一个DBMS传输到另一个DBMS,甚至有时在不同版本的DBMS之间传输。

    要记住的是,DBMS一次只能执行一个联接:它从两个初始表开始,联接这些表,然后获取该操作的结果并将其联接到下一个表。每个步骤的目标都是最小化中间结果集中的行数(更正确地说,是最小化必须读取以生成中间结果的块数,但这通常意味着行数最少)。

        7
  •  1
  •   Alicia ibre5041    11 年前

    如果你硬编码你的 在哪里? 标准如下:

    SELECT StuCertKey, StuKey FROM stu 
    WHERE stuKey in (/* list 50 values of StuKey here */)
    

    如果速度仍然很慢,你会遇到某种内部问题。如果速度更快,那么索引就不是你的瓶颈,而是 联接 你要做的是创造 在哪里? 过滤器。

    注意 SELECT * 如果有许多大的列,特别是有斑点的列,速度会非常慢。

        8
  •  1
  •   reZa    7 年前

    检查索引静态。

    重新计算聚集索引统计信息将解决这个问题。

    在我的案例中,我正在寻找40米记录中的30条记录。 执行计划说它正在通过聚集索引,但它花费了大约200毫秒,而且索引没有进行碎片整理。重新计算它的统计数据后,它将在10毫秒内完成!

        9
  •  0
  •   shA.t Rami Jamleh    9 年前

    重建索引并计算统计?

    我能想到的另一种加快速度的方法是对表进行分区,这可能是可能的,也可能是不可能的。