我已经提取了一个没有索引的 FK 列表。
如果 FK 上没有专用索引,但它们是用于覆盖查询的更广泛索引的一部分,是否应该创建专用索引?
例如下面的 mytable 是一个 20 列的表,其中一个 varchar(255) 和其余的 ints、datetime 或 smallints。
它缺少索引
AdvertiserId
Dirty
MasterAdGroupId
AdvertiserID 缺少外键索引,但 [advertiserID] 是索引的一部分,其中 [dirty]&[error] 是 smallints。这应该有自己的专用索引吗?
我应该删除其中一些索引并将它们与包含的列组合吗?那么我的外键有专用索引吗?
index_keys
-------------
[AdvertiserAdGroupId]
[AdvertiserHierarchyId]
[AdvertiserHierarchyId], [AdvertiserAdGroupId], [MasterAdGroupId]
[AdvertiserAdGroupCode]
[AdvertiserAdGroupId], [MasterAdGroupId], [AdvertiserId]
[AdvertiserId], [Dirty], [Error]
[MasterAdGroupId], [Deleted], [AdvertiserAdGroupId]
[AdvertiserHierarchyId], [Error], [AdvertiserAdGroupId], [MasterAdGroupId], [Deleted]
[Error], [AdvertiserHierarchyId], [Dirty], [AdvertiserAdGroupId]
[MasterAdGroupId], [AdvertiserAdGroupId], [AdvertiserHierarchyId]
[AdvertiserId], [AdvertiserAdGroupCode], [LastSyncedDate], [CreatedDate]
[AdvertiserId], [Deleted], [Paused], [AdvertiserAdGroupCode]
这取决于表的访问模式。如果该列被大量搜索(并且理想情况下是高度选择性的),那么是的,您绝对应该在该列上有一个索引,将该列作为定义中的第一个键列。
问题中给出的内容有些不清楚,您提出的问题有点……困惑,所以让我们退后一步。
在 SQL Server 2005+ 中,索引定义中最重要的三个部分是:
确定索引排序顺序的键列。这意味着键列的顺序非常重要,因为 SQL Server 通过在第一个键列中搜索值来使用索引,然后在第二个键列中搜索值,依此类推。
包含的列,它们是标记到索引结构上的行数据的副本。指定的包含列的顺序无关紧要。
索引是否唯一?这意味着索引键只能包含列值的唯一组合。
(虽然这与手头的讨论无关,但为了完整起见,我将在此处提及:SQL Server 2008+ 引入了过滤索引的概念,它仅包括索引中满足谓词的行。)
您应该做的第一件事是索引合并。这涉及使用上述几点来组合具有共同点的索引。
例如,考虑以下两个索引:
这些索引共享前导键列
C1
. 包含的列可以按任何顺序指定,因此这两个索引可以组合如下:如果索引键的组成或其他属性不同,则必须非常小心。考虑这些索引:
现在的决定并不那么容易。您必须根据工作负载、哪些查询命中表以及数据本身的选择性来确定要做什么。
所以要更直接地回答这个问题:如果您当前有一个或多个索引,其中感兴趣的列是这些索引中的第一个键列,那么您不必添加更多索引,因为您拥有的索引很有用。
如果该列被频繁搜索并且没有以该列作为第一个键列的索引,则应创建一个将该列作为第一个键列的索引。(根据查询要求,您可能还想为键或包含的列指定其他列。)
如果不经常搜索该列,您可能会避免将其包含在另一个索引(不是第一个键列)中:可以通过扫描包含该列的索引来满足查询。这不如索引查找效率高(由于许多原因),但如果此操作不经常发生,并且这种情况下的性能是可以接受的,那么您可能会没事。
请记住,创建索引不是免费的——它们占用了数据空间、日志空间、缓存内存,并且可能会减慢
INSERT
//活动(话虽如此,创建索引还有其他UPDATE
优势)。这是你必须为你的环境争取的平衡。DELETE
如果要使用索引,它就会很有用。这取决于您执行的查询类型、数据插入父表的方式(假设 FK 处于活动状态)以及父表的大小。例如,如果 MasterAdGroupId 是 MasterAdGroup 表的键,而该表只有 5 行,则在其上定义索引将毫无用处。此外,名为“Dirty”的列听起来像一个二进制列,我认为你不会获得索引它的巨大价值。
如其他答案所述,您要确保将使用索引。Kevin Kline 有一个关于如何检查和查看正在使用的索引的精彩视频。这是他用来检查未使用索引的 sql 代码: