作为“什么是索引以及如何使用它们来优化我的数据库中的查询? ”的后续行动,我正在尝试了解索引,哪些列是好的索引候选?专门针对 MS SQL 数据库?
经过一番谷歌搜索后,我读到的所有内容都表明,通常会增加且唯一的列是一个很好的索引(比如 MySQL 的 auto_increment 之类的东西),我理解这一点,但我使用的是 MS SQL,并且我使用的是 GUID 作为主键,所以看起来索引不会使 GUID 列受益...
作为“什么是索引以及如何使用它们来优化我的数据库中的查询? ”的后续行动,我正在尝试了解索引,哪些列是好的索引候选?专门针对 MS SQL 数据库?
经过一番谷歌搜索后,我读到的所有内容都表明,通常会增加且唯一的列是一个很好的索引(比如 MySQL 的 auto_increment 之类的东西),我理解这一点,但我使用的是 MS SQL,并且我使用的是 GUID 作为主键,所以看起来索引不会使 GUID 列受益...
索引可以在查询优化和从表中快速搜索结果中发挥重要作用。所以选择要索引的列是最重要的一步。有两个主要的地方我们可以考虑索引: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 用于索引,因为它位于 JOIN 子句中。因此可以考虑对 WHERE 子句或 JOIN 子句中的每个字段进行索引。
以下列表还提供了一些提示,当您打算在表中创建索引时应始终牢记这些提示:
更新(2015 年 2 月 23 日):
任何索引(好/坏)都会增加插入和更新时间。
根据您的索引(索引数量和类型),搜索结果。如果您的搜索时间会因为索引而增加,那么这就是糟糕的索引。
很可能在任何一本书中,“索引页”都可能有章节起始页、主题页码起始页以及子主题页起始页。索引页面中的一些说明会有所帮助,但更详细的索引可能会使您感到困惑或吓到您。索引也有记忆。
索引选择应该是明智的。请记住,并非所有列都需要索引。
有些人在这里回答了类似的问题:你怎么知道什么是好的索引?
基本上,这实际上取决于您将如何查询数据。您需要一个能够快速识别与查询相关的一小部分数据集的索引。如果您从不按日期戳查询,则不需要索引,即使它大多是唯一的。如果您所做的只是获取某个日期范围内发生的事件,那么您肯定想要一个。在大多数情况下,关于性别的索引是没有意义的——但如果你所做的只是获取所有男性的统计数据,并且单独获取所有女性的统计数据,那么创建一个索引可能是值得的。弄清楚您的查询模式将是什么,并访问哪个参数最能缩小搜索空间,这就是您的最佳索引。
还要考虑你创建的索引类型——B-trees 适用于大多数事情并允许范围查询,但哈希索引让你直截了当(但不允许范围)。其他类型的索引也有其他优点和缺点。
祝你好运!
这完全取决于您希望对表提出什么查询。如果您要求 X 列具有特定值的所有行,则如果无法使用索引,则必须进行全表扫描。
在以下情况下,索引将很有用:
如果出现以下情况,它们将无用:
主键列通常非常适合索引,因为它们是唯一的并且通常用于查找行。
任何将经常用于从表中提取数据的列都应该被索引。
这包括:外键 -
select * from tblOrder where status_id=:v_outstanding
描述性字段 -
select * from tblCust where Surname like "O'Brian%"
列不需要是唯一的。事实上,在搜索异常时,您可以从二进制索引中获得非常好的性能。
select * from tblOrder where paidYN='N'
一般来说(我不使用 mssql,所以不能具体评论),主键是很好的索引。它们是唯一的,并且必须具有指定的值。(此外,主键生成的索引非常好,以至于它们通常会自动创建一个索引。)
索引实际上是已排序以允许二进制搜索(比线性搜索快得多)的列的副本。数据库系统可能会使用各种技巧来进一步加快搜索速度,尤其是在数据比简单数字更复杂的情况下。
我的建议是最初不要使用任何索引并分析您的查询。如果某个特定查询(例如按姓氏搜索人员)运行频率很高,请尝试再次在相关属性和配置文件上创建索引。如果查询的速度明显加快,而插入和更新的速度可以忽略不计,请保留索引。
(抱歉,如果我重复您在另一个问题中提到的内容,我之前没有遇到过。)
GUID 列不是索引的最佳候选者。索引最适合数据类型的列,该数据类型可以给出一些有意义的顺序,即排序(整数、日期等)。
列中的数据是否普遍增加并不重要。如果您在列上创建索引,该索引将创建它自己的数据结构,该结构将简单地引用表中的实际项目,而不考虑存储顺序(非聚集索引)。然后,例如可以对您的索引数据结构执行二进制搜索以提供快速检索。
还可以创建一个“聚集索引”,对您的数据进行物理重新排序。但是,每个表只能有一个,而可以有多个非聚集索引。
这实际上取决于您的查询。例如,如果您几乎只写入表,那么最好不要有任何索引,它们只会减慢写入速度并且永远不会被使用。您用于与另一个表连接的任何列都是索引的良好候选者。
此外,请阅读有关缺失索引功能的信息。它监视对您的数据库使用的实际查询,并可以告诉您哪些索引可以提高性能。
您的主键应始终是索引。(事实上,如果它没有被 MS SQL 自动索引,我会感到惊讶。)您还应该经常索引SELECT
列ORDER
;它们的目的是快速查找单个值和更快的排序。
索引too
许多列的唯一真正危险是减慢对大表中行的更改,因为索引也都需要更新。如果您真的不确定要索引什么,只需为最慢的查询计时,查看最常使用的列,然后为它们编制索引。然后看看他们的速度有多快。
出于多种原因,按升序或降序排序的数字数据类型是很好的索引。首先,数字通常比字符串(varchar、char、nvarchar 等)计算速度更快。其次,如果您的值没有排序,则可能需要对行和/或页面进行洗牌以更新您的索引。这是额外的开销。
如果您使用 SQL Server 2005 并设置使用 uniqueidentifiers (guids),并且不需要它们是随机的,请查看顺序 uniqueidentifier 类型。
最后,如果您谈论的是聚集索引,那么您谈论的是物理数据的种类。如果你有一个字符串作为你的聚集索引,那可能会变得很难看。
经验法则是在 WHERE、ORDER BY 和 GROUP BY 子句中经常使用的列,或者在连接中经常使用的任何列。请记住,我指的是索引,而不是主键
不要给出一个“香草味”的答案,但这真的取决于你如何访问数据
如果您使用 GUID,它应该会更快。假设你有记录
如果你有索引(二分查找,你可以在 O(lg n) 时间内找到你要查找的记录的物理位置,而不是按顺序查找 O(n) 时间。这是因为你不知道你有哪些记录在你的桌子上。
最佳索引取决于表的内容以及您要完成的任务。
举个例子 一个成员数据库,其主键是成员社会保障号。我们选择 SS 是因为应用程序主要以这种方式引用个人,但您还想创建一个搜索功能,该功能将利用成员的名字和姓氏。然后我建议在这两个字段上创建一个索引。
您应该首先找出要查询的数据,然后确定需要索引的数据。