【问题标题】:sql table optimization: primary and secondary indexessql表优化:主次索引
【发布时间】:2011-12-26 03:28:22
【问题描述】:

为了安全起见,人们是否通常将表中的每一列都设为二级索引,以防客户决定使用任一字段来搜索记录?

搜索是否先经过二级索引,然后到主键?从而缩小到请求的数据?

如果您已经有一个作为主键的列,那么拥有二级索引有什么意义?

【问题讨论】:

  • 您的问题似乎是关于索引而不是键。其他人也是这么解释的,我现在已经相应地编辑了这个问题。如果您真的想询问密钥,请撤消我的编辑并澄清您的问题,因为那将是一个截然不同的问题。

标签: sql database database-design


【解决方案1】:

(以下响应适用于 Sql Server。某些部分可能因其他 DBMS 而异。)

最后一个问题首先:“如果您已经有一个作为主键的列,那么拥有辅助键有什么意义?”我以表"People (Id int primary key, firstname varchar(40), middlename varchar(40), lastname varchar(40))". 为例进行说明 现在考虑查询"select * from people where lastname = 'flynn'". 如果lastname 列上没有索引,则将依次扫描该表以查找匹配项。必须访问每一行。主键索引在这里根本没有帮助。如果您索引 lastname 列,则可以更快地找到结果。

您通常只会索引那些对您的应用程序问题查询有用的列。如果您的查询在名为“MiddleName”的列上从未有连接或 where 条件,那么索引该列不会带来任何好处。您不想添加不必要的索引,因为它们会增加涉及该列的数据插入和更新的成本。

我们通常说 Sql Server 在查询中对每个表实例只使用一个索引。所以像“select * from people where firstname='Elroy' and lastname = 'Flynn'”这样的查询最多会使用一个索引,即使 firstname 和 lastname 都有索引。 Sql Server 将根据从数据值中收集的统计信息选择一个或另一个索引。

为了完整起见,我必须在这里稍微深入一点,并讨论聚集索引与非聚集索引。一张表只能有一个聚集索引:其余的都是非聚集索引。尽管有上一段,当使用非聚集索引来解析查询时,索引查找会产生一个中间结果,该结果是与聚集索引(通常是主键)相关联的键的完整值。也就是说,每个非聚集索引的叶子都包含聚集键值,而不是行指针。找到此聚集键后,聚集索引随后用于解析对特定数据库行的查找。因此,最终,所有索引查找最终都会使用聚集索引。

不过,出于实际目的,通常说每个表实例只使用一个索引就足够了,而且更简单。请注意,如果一个表在查询中具有别名以使其出现多次,则可以为不同的引用使用不同的索引。例如,“select * from people p1 join people p2 on p1.firstname = p2.lastname" 可以在 p1 实例上使用名字索引,在 p2 实例上使用姓氏索引。

http://msdn.microsoft.com/en-us/library/aa933131(v=SQL.80).aspx

【讨论】:

    【解决方案2】:

    通常您只索引需要的列。添加额外的索引通常会被认为是过早的优化。

    大多数优化器会找出最快的方法来找到最少的记录。这可能是使用和索引,但可能是全表扫描。如果有多个索引可以使用,通常只使用一个,并将结果记录与其余标准进行比较。如果使用多个索引,则需要匹配结果集,并消除在两个索引中都没有找到的记录。

    对于自然键可能会更改或非常(故意模糊)长的表,通常使用代理键。在这种情况下,自然键将被索引为辅助唯一键。在某些情况下,可能存在竞争的自然键,在这种情况下,所有自然键都将具有唯一索引。

    【讨论】:

      【解决方案3】:

      还有一个没有提到的项目,每个额外的索引都必须维护。因此,如果您的索引以几种不同的组合覆盖所有列,它们不仅会占用大量空间,而且每次更新/插入/删除都有可能更改这些索引中的一个或多个。这将导致这些操作在许多情况下被减慢。

      这总是一个权衡。您拥有的索引越多,服务器为使它们保持最新状态所要做的工作就越多,但是您越有可能拥有至少一个能够涵盖您在该表中抛出的任何查询的索引。

      【讨论】:

        【解决方案4】:

        “在安全方面”?没有。

        索引用空间和插入时间换取选择时间。不必要的键会占用磁盘空间并降低插入速度,以换取加速从未发生过的查询。

        与所有优化一样,进行查询优化最后 -- 构建系统然后观察其行为。

        高度技术性的主要/次要区别。所有索引的存在都是为了加快查询和/或强制执行某些完整性约束。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-04-16
          • 2018-07-14
          • 2011-01-18
          • 2012-08-05
          • 1970-01-01
          • 2019-05-26
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多