What columns generally make good indexes?

作为“ 什么是索引以及如何使用它们来优化数据库中的查询?”的后续,我试图了解索引,哪些列是好的索引候选者?特别是对于 MS SQL 数据库?

经过一些谷歌,我所读到的一切都表明,列通常是增加和唯一的是一个很好的索引(像 MySQL 的自动增量) ,我理解这一点,但我正在使用 MS SQL 和我使用 GUID 的主键,所以索引似乎不会受益于 GUID 列..。

103950 次浏览

一般来说(我不使用 mssql,所以不能具体注释) ,主键是很好的索引。它们是唯一的,并且必须具有指定的值。(此外,主键创建的索引非常好,通常会自动创建一个索引。)

索引实际上是已经排序以允许二进制搜索(比线性搜索快得多)的列的副本。数据库系统可以使用各种技巧来加快搜索速度,特别是当数据比简单的数字更复杂时。

我的建议是,最初不要使用任何索引,而是对查询进行概要分析。如果经常运行某个特定查询(例如按姓氏搜索人员) ,请再次尝试在相关属性和配置文件上创建索引。如果查询的速度明显加快,插入和更新的速度几乎可以忽略不计,则保留索引。

(如果我重复了你另一个问题中提到的内容,我道歉,我以前没有遇到过这个问题。)

GUID 列不是索引的最佳候选列。索引最适合具有可以给出一些有意义顺序的数据类型的列,即排序(整数、日期等)。

列中的数据通常是否在增加并不重要。如果在列上创建索引,索引将创建自己的数据结构,该结构将简单地引用表中的实际项,而不关心存储顺序(非聚集索引)。然后,例如,可以对索引数据结构执行二进制搜索以提供快速检索。

还可以创建一个“聚集索引”,该索引将对数据进行物理重新排序。但是,每个表只能有一个这样的索引,而可以有多个非聚集索引。

如果您使用的是 GUID,那么应该会更快。 假设你有记录

  1. 100
  2. 200
  3. 3000
  4. ....

如果您有一个索引(二进制搜索,您可以在 O (lgn)时间内找到正在查找的记录的物理位置,而不必依次搜索 O (n)时间。这是因为您不知道表中有哪些记录。

这真的取决于您的查询。例如,如果您几乎只写一个表,那么最好不要有任何索引,它们只会减慢写操作,而且永远不会被使用。用于与另一个表联接的任何列都是索引的很好候选列。

另外,阅读有关丢失索引特性的内容。它监视对数据库使用的实际查询,并能告诉您哪些索引可以提高性能。

有些人在这里回答了一个类似的问题: 你怎么知道什么是好的索引?

基本上,这取决于如何查询数据。您希望索引能够快速标识与查询相关的数据集的一个小子集。如果您从不通过日期戳查询,则不需要对其进行索引,即使它大多数情况下是唯一的。如果您所做的只是获取在特定日期范围内发生的事件,那么您肯定需要一个。在大多数情况下,性别指数是没有意义的——但是如果你所做的只是得到所有男性的统计数据,并且分别得到所有女性的统计数据,那么你可能值得花时间去创建一个。弄清楚您的查询模式将是什么,访问哪个参数将最大限度地缩小搜索空间,这就是最好的索引。

还要考虑您创建的索引类型—— B 树对于大多数情况都很有用,并且允许范围查询,但是散列索引可以让您直奔主题(但是不允许范围)。其他类型的索引有其他的优缺点。

祝你好运!

Ol’经验法则是在 WHERE、 ORDERBY 和 GROUPBY 子句中经常使用的列,或者似乎在联接中经常使用的任何列。请记住,我指的是索引,而不是主键

我不想给出一个“普通”的答案,但这确实取决于您如何访问数据

最佳索引取决于表的内容和您要完成的任务。

一个成员数据库的一个成员社会保障号码的主键。我们选择 S.S. 是因为应用程序主要以这种方式引用个人,但是你也想创建一个搜索函数来利用成员的姓和名。然后我建议在这两个字段上创建一个索引。

您应该首先找出要查询的数据,然后确定需要索引哪些数据。

您的主键应该始终是一个索引。(事实上,如果它没有被 MS SQL 自动索引,我会感到惊讶。)您还应该频繁地索引 SELECTORDER列; 它们的目的是快速查找单个值和快速排序。

too多列建立索引的唯一真正危险是减慢对大型表中行的更改,因为索引也都需要更新。如果您真的不确定要索引什么内容,那么只需计算最慢的查询的时间,查看哪些列最常被使用,然后对它们进行索引。然后看看他们有多快。

这完全取决于您希望询问关于表的什么查询。如果您要求所有列 X 具有某个值的行,那么如果不能使用索引,则必须进行全表扫描。

如果:

  • 列具有高度的唯一性
  • 您经常需要查找 纵队。

They will not be useful if:

  • You are selecting a large % (>10-20%) of the rows in the table
  • 额外的空间使用是一个问题
  • 您希望最大化插入性能。表上的每个索引都会降低插入和更新性能,因为它们必须在每次数据更改时更新。

Primary key columns are typically great for indexing because they are unique and are often used to lookup rows.

任何将定期用于从表中提取数据的列都应该建立索引。

这包括: 外国钥匙-

select * from tblOrder where status_id=:v_outstanding

描述性字段-

select * from tblCust where Surname like "O'Brian%"

列不需要是唯一的。实际上,在搜索异常时,可以从二进制索引获得非常好的性能。

select * from tblOrder where paidYN='N'

由于多种原因,按升序或降序排列的数值数据类型是很好的索引。首先,计算数字通常比计算字符串(varchar、 char、 nvarchar 等)更快。其次,如果您的值没有排序,那么可能需要对行和/或页进行洗牌以更新索引。那是额外的开销。

If you're using SQL Server 2005 and set on using uniqueidentifiers (guids), and do NOT need them to be of a random nature, check out the sequential uniqueidentifier type.

Lastly, if you're talking about clustered indexes, you're talking about the sort of the physical data. If you have a string as your clustered index, that could get ugly.

索引在查询优化和从表中快速搜索结果方面起着重要作用。最重要的步骤是选择要编制索引的列。有两个主要的地方可以考虑索引: WHERE 子句中引用的列和 JOIN 子句中使用的列。简而言之,应该对这些列进行索引,您需要根据这些列搜索特定的记录。假设我们有一个名为 Buy 的表,其中 SELECT 查询使用如下索引:

SELECT
buyer_id /* no need to index */
FROM buyers
WHERE first_name='Tariq' /* consider indexing */
AND last_name='Iqbal'   /* consider indexing */

由于在 SELECT 部分引用了“ buy _ id”,MySQL 将不会使用它来限制所选择的行。因此,没有必要对其进行索引。下面是另一个与上面的例子有点不同的例子:

SELECT
buyers.buyer_id, /* no need to index */
country.name    /* no need to index */
FROM buyers LEFT JOIN country
ON buyers.country_id=country.country_id /* consider indexing */
WHERE
first_name='Tariq' /* consider indexing */
AND
last_name='Iqbal' /* consider indexing */

According to the above queries first_name, last_name columns can be indexed as they are located in the WHERE clause. Also an additional field, country_id from country table, can be considered for indexing because it is in a JOIN clause. So indexing can be considered on every field in the WHERE clause or a JOIN clause.

下面的列表还提供了一些在为表创建索引时应始终牢记的提示:

  • Only index those columns that are required in WHERE and ORDER BY clauses. Indexing columns in abundance will result in some disadvantages.
  • 尝试利用 MySQL 的“索引前缀”或“多列索引”特性。如果创建 INDEX (first _ name,last _ name)等索引,则不要创建 INDEX (first _ name)。但是,不建议在所有搜索案例中使用“索引前缀”或“多列索引”。
  • 对考虑索引的列使用 NOTNULL 属性,这样就永远不会存储 NULL 值。
  • Use the --log-long-format option to log queries that aren’t using indexes. In this way, you can examine this log file and adjust your queries accordingly.
  • EXPLAIN 语句可以帮助您了解 MySQL 将如何执行查询。它显示了如何以及以什么顺序连接表。这对于确定如何编写优化的查询以及是否需要对列进行索引非常有用。

最新消息(2015年2月23日) :

任何索引(好/坏)都会增加插入和更新时间。

Depending on your indexes (number of indexes and type), result is searched. If your search time is gonna increase because of index then that's bad index.

在任何一本书中,“索引页”都可以有章节开始页、主题页号开始页,也可以有子主题页开始页。索引页面中的一些说明有所帮助,但是更详细的索引可能会使您感到困惑或害怕。索引也有内存。

索引选择应该是明智的。请记住,并非所有列都需要索引。