sql表优化: primary and secondary indexes

标签 sql database database-design

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

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

如果您已经有一个主键列,那么使用二级索引有什么意义?

最佳答案

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

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

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

我们通常说 Sql Server 在查询中每个表实例只使用一个索引。因此,像“select * from people where firstname='Elroy' and lastname = 'Flynn'”这样的查询将最多使用一个索引,即使名字和姓氏都有索引。 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

关于sql表优化: primary and secondary indexes,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8632742/

相关文章:

ruby - 使用 Rails 安装程序安装后测试 sqlite3 的正确安装

mysql - 从每个领域获得总值(value)?

database - 在 influxdb 0.9.x 中合并时间序列

database-design - varchar(1) 与 char(1) 之间的性能

php - 无法从 MySQL 数据库检索所有图像

mysql - 一次触发多个操作,不起作用

mysql - 如何使用 Spring Data JPA 从表中的列中检索唯一字符串字段的列表?

mysql - 如何从 MySQL 中的 2 个表中选择最大值

sql-server - 存储过程的位置会影响它的性能吗?

mysql - 存储具有不同属性的类似产品