作为我试图了解索引的“What are indexes and how can I use them to optimise queries in my database?”的后续内容,哪些列是好的索引候选者?特别是对于MS SQL数据库?
经过一些谷歌搜索后,我读到的所有内容都表明,通常增加且唯一的列会产生一个很好的索引(比如MySQL的auto_increment),我理解这一点,但我使用的是MS SQL,我使用GUID作为主键,所以似乎索引不会使GUID列受益......
答案 0 :(得分:87)
索引可以在查询优化中发挥重要作用,并从表中快速搜索结果。因此,选择要编制索引的列是最重要的步骤。我们可以考虑索引的两个主要位置:WHERE子句中引用的列和JOIN子句中使用的列。简而言之,应该索引这些列,以便您搜索特定记录。假设,我们有一个名为buyer的表,其中SELECT查询使用如下索引:
SELECT
buyer_id /* no need to index */
FROM buyers
WHERE first_name='Tariq' /* consider to use index */
AND last_name='Iqbal' /* consider to use index */
由于SELECT部分引用了“buyer_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 to use index */
WHERE
first_name='Tariq' /* consider to use index */
AND
last_name='Iqbal' /* consider to use index */
根据上面的查询first_name,last_name列可以索引,因为它们位于WHERE子句中。另外一个字段country_id来自country表,可以考虑进行索引,因为它在JOIN子句中。因此,可以在WHERE子句中的每个字段或JOIN子句中考虑索引。
以下列表还提供了一些在打算在表中创建索引时应始终牢记的提示:
更新(2015年2月23日):
任何索引(好/坏)都会增加插入和更新时间。
根据索引(索引数和类型),搜索结果。如果你的搜索时间会因索引而增加,那么那就是糟糕的索引。
可能在任何一本书中,“索引页面”都可以有章节开始页面,主题页面编号开始,也可以有子主题页面开始。索引页面中的一些说明有所帮助,但更详细的索引可能会让您感到困惑或吓到您。索引也有记忆。
指数选择应该是明智的。请记住,并非所有列都需要索引。
答案 1 :(得分:18)
有些人在这里回答了类似的问题:How do you know what a good index is?
基本上,它实际上取决于您将如何查询数据。您需要一个索引,可以快速识别与查询相关的数据集的一小部分。如果您从不按日期戳查询,则不需要索引,即使它主要是唯一的。如果您所做的只是获取某个日期范围内发生的事件,那么您肯定需要一个。在大多数情况下,性别指数毫无意义 - 但如果你所做的只是得到关于所有男性的统计数据,并且分别关于所有女性,那么创建一个女性可能是值得的。弄清楚你的查询模式是什么,访问哪个参数最大限度地缩小搜索空间,这是你最好的索引。
还要考虑你所做的索引类型 - B树对大多数事情都有好处并且允许范围查询,但是哈希索引会让你直截了当(但不允许范围)。其他类型的索引有其他优点和缺点。
祝你好运!答案 2 :(得分:6)
这完全取决于您希望询问有关表格的查询。如果要求列X具有特定值的所有行,则如果无法使用索引,则必须执行全表扫描。
索引在以下情况下非常有用:
如果符合以下条件,它们将无用:
主键列通常非常适合索引,因为它们是唯一的,通常用于查找行。
答案 3 :(得分:5)
一般情况下(我不使用mssql所以不能专门评论),主键制作好的索引。它们是唯一的,必须具有指定的值。 (此外,主键可以生成如此好的索引,通常会自动创建索引。)
索引实际上是已经排序以允许二进制搜索的列的副本(这比线性搜索快得多)。数据库系统可能会使用各种技巧来进一步加快搜索速度,特别是如果数据比简单数字更复杂的话。
我的建议是最初不要使用任何索引并对您的查询进行概要分析。如果经常运行特定查询(例如,通过姓氏搜索人员),请尝试再次在相关属性和配置文件上创建索引。如果查询速度明显加快,插入和更新速度可忽略不计,请保留索引。
(道歉,如果我重复你在其他问题中提到的内容,我之前没有遇到过。)
答案 4 :(得分:4)
任何将定期用于从表中提取数据的列都应编入索引。
这包括: 外键 -
select * from tblOrder where status_id=:v_outstanding
描述性字段 -
select * from tblCust where Surname like "O'Brian%"
列不需要是唯一的。事实上,在搜索异常时,您可以从二进制索引中获得非常好的性能。
select * from tblOrder where paidYN='N'
答案 5 :(得分:3)
GUID列不是索引的最佳候选者。索引最适合具有可以给出一些有意义顺序的数据类型的列,即排序(整数,日期等)。
列中的数据是否通常增加并不重要。如果在列上创建索引,索引将创建它自己的数据结构,该结构将简单地引用表中的实际项而不关心存储的顺序(非聚集索引)。然后,例如,可以对索引数据结构执行二进制搜索,以提供快速检索。
还可以创建一个“聚集索引”,它将对您的数据进行物理重新排序。但是,每个表只能有一个这样的表,而您可以有多个非聚集索引。
答案 6 :(得分:3)
这实际上取决于您的查询。例如,如果您几乎只写一个表,那么最好不要有任何索引,它们只会减慢写入速度并且永远不会被使用。您用于与另一个表联接的任何列都是索引的良好候选者。
另外,请阅读Missing Indexes功能。它监视对数据库使用的实际查询,并可以告诉您哪些索引可以改善性能。
答案 7 :(得分:1)
您的主键应始终是索引。 (事实上,如果它没有被MS SQL自动索引,我会感到惊讶。)你还应经常为SELECT
或ORDER
列编制索引;它们的目的是快速查找单个值并加快排序。
索引too
多列的唯一真正危险是减慢对大型表中行的更改,因为索引都需要更新。如果你真的不确定要索引什么,只需花时间查询最慢的查询,查看最常使用的列,并将它们编入索引。然后看看它们的速度有多快。
答案 8 :(得分:1)
由于多种原因,按升序或降序排序的数字数据类型是良好的索引。首先,数字通常比字符串(varchar,char,nvarchar等)更快评估。其次,如果您的值未被排序,则可能需要对行和/或页面进行洗牌以更新索引。这是额外的开销。
如果您正在使用SQL Server 2005并设置使用uniqueidentifiers(guids),并且不需要它们具有随机性,请查看顺序uniqueidentifier类型。
最后,如果您正在讨论聚簇索引,那么您谈论的是物理数据的类型。如果你有一个字符串作为你的聚集索引,那可能会很难看。
答案 9 :(得分:0)
如果您使用GUID,它应该更快。 假设你有记录
如果你有索引(二进制搜索,你可以在O(lg n)时间内找到你要查找的记录的物理位置,而不是按顺序搜索O(n)时间。这是因为你不知道是什么你在桌子上的记录。
答案 10 :(得分:0)
ol'经验法则是在WHERE,ORDER BY和GROUP BY子句中使用很多的列,或者经常在连接中使用的任何列。请记住,我指的是索引,而不是主键
不要给出'vanilla-ish'答案,但这实际上取决于您访问数据的方式
答案 11 :(得分:0)
最佳索引取决于表的内容以及您要完成的任务。
示例带有成员社会保障Numnber主键的成员数据库。我们选择S.S.,因为应用程序priamry以这种方式引用个人,但您还想创建一个将使用成员名和姓的搜索功能。然后我会建议在这两个字段上创建一个索引。
您应首先找出要查询的数据,然后确定需要索引的数据。