AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 20248
Accepted
DamagedGoods
DamagedGoods
Asked: 2012-07-03 02:53:10 +0800 CST2012-07-03 02:53:10 +0800 CST 2012-07-03 02:53:10 +0800 CST

SQL server 索引外键,覆盖索引包含的列

  • 772

我已经提取了一个没有索引的 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 index-tuning
  • 3 3 个回答
  • 3942 Views

3 个回答

  • Voted
  1. Best Answer
    Jon Seigel
    2012-07-03T06:34:08+08:002012-07-03T06:34:08+08:00

    如果 FK 上没有专用索引,但它们是用于覆盖查询的更广泛索引的一部分,是否应该创建专用索引?

    这取决于表的访问模式。如果该列被大量搜索(并且理想情况下是高度选择性的),那么是的,您绝对应该在该列上有一个索引,将该列作为定义中的第一个键列。

    我应该删除其中一些索引并将它们与包含的列组合吗?那么我的外键有专用索引吗?

    问题中给出的内容有些不清楚,您提出的问题有点……困惑,所以让我们退后一步。

    在 SQL Server 2005+ 中,索引定义中最重要的三个部分是:

    1. 确定索引排序顺序的键列。这意味着键列的顺序非常重要,因为 SQL Server 通过在第一个键列中搜索值来使用索引,然后在第二个键列中搜索值,依此类推。

    2. 包含的列,它们是标记到索引结构上的行数据的副本。指定的包含列的顺序无关紧要。

    3. 索引是否唯一?这意味着索引键只能包含列值的唯一组合。

    (虽然这与手头的讨论无关,但为了完整起见,我将在此处提及:SQL Server 2008+ 引入了过滤索引的概念,它仅包括索引中满足谓词的行。)

    您应该做的第一件事是索引合并。这涉及使用上述几点来组合具有共同点的索引。

    例如,考虑以下两个索引:

    CREATE INDEX IX_1 ON [dbo].[t1](C1) INCLUDE(C3, C4);
    CREATE INDEX IX_2 ON [dbo].[t1](C1, C2) INCLUDE(C5);
    

    这些索引共享前导键列C1. 包含的列可以按任何顺序指定,因此这两个索引可以组合如下:

    CREATE INDEX IX_3 ON [dbo].[t1](C1, C2) INCLUDE(C3, C4, C5);
    

    如果索引键的组成或其他属性不同,则必须非常小心。考虑这些索引:

    CREATE INDEX IX_4 ON [dbo].[t1](C1, C3) INCLUDE(C4);
    CREATE UNIQUE INDEX IX_5 ON [dbo].[t1](C1, C4) INCLUDE(C5);
    

    现在的决定并不那么容易。您必须根据工作负载、哪些查询命中表以及数据本身的选择性来确定要做什么。

    所以要更直接地回答这个问题:如果您当前有一个或多个索引,其中感兴趣的列是这些索引中的第一个键列,那么您不必添加更多索引,因为您拥有的索引很有用。

    如果该列被频繁搜索并且没有以该列作为第一个键列的索引,则应创建一个将该列作为第一个键列的索引。(根据查询要求,您可能还想为键或包含的列指定其他列。)

    如果不经常搜索该列,您可能会避免将其包含在另一个索引(不是第一个键列)中:可以通过扫描包含该列的索引来满足查询。这不如索引查找效率高(由于许多原因),但如果此操作不经常发生,并且这种情况下的性能是可以接受的,那么您可能会没事。

    请记住,创建索引不是免费的——它们占用了数据空间、日志空间、缓存内存,并且可能会减慢INSERT//活动(话虽如此,创建索引还有其他UPDATE优势)。这是你必须为你的环境争取的平衡。DELETE

    • 7
  2. NoChance
    2012-07-03T03:30:32+08:002012-07-03T03:30:32+08:00

    如果要使用索引,它就会很有用。这取决于您执行的查询类型、数据插入父表的方式(假设 FK 处于活动状态)以及父表的大小。例如,如果 MasterAdGroupId 是 MasterAdGroup 表的键,而该表只有 5 行,则在其上定义索引将毫无用处。此外,名为“Dirty”的列听起来像一个二进制列,我认为你不会获得索引它的巨大价值。

    • 0
  3. DForck42
    2012-07-04T11:49:07+08:002012-07-04T11:49:07+08:00

    如其他答案所述,您要确保将使用索引。Kevin Kline 有一个关于如何检查和查看正在使用的索引的精彩视频。这是他用来检查未使用索引的 sql 代码:

    SELECT 
    o.name
    , indexname=i.name
    , i.index_id   
    , reads=user_seeks + user_scans + user_lookups   
    , writes =  user_updates   
    , rows = (SELECT SUM(p.rows) FROM sys.partitions p WHERE p.index_id = s.index_id AND s.object_id = p.object_id)
    , CASE
        WHEN s.user_updates < 1 THEN 100
        ELSE 1.00 * (s.user_seeks + s.user_scans + s.user_lookups) / s.user_updates
      END AS reads_per_write
    , 'DROP INDEX ' + QUOTENAME(i.name) 
    + ' ON ' + QUOTENAME(c.name) + '.' + QUOTENAME(OBJECT_NAME(s.object_id)) as 'drop statement'
    FROM sys.dm_db_index_usage_stats s  
    INNER JOIN sys.indexes i ON i.index_id = s.index_id AND s.object_id = i.object_id   
    INNER JOIN sys.objects o on s.object_id = o.object_id
    INNER JOIN sys.schemas c on o.schema_id = c.schema_id
    WHERE OBJECTPROPERTY(s.object_id,'IsUserTable') = 1
    AND s.database_id = DB_ID()   
    AND i.type_desc = 'nonclustered'
    AND i.is_primary_key = 0
    AND i.is_unique_constraint = 0
    AND (SELECT SUM(p.rows) FROM sys.partitions p WHERE p.index_id = s.index_id AND s.object_id = p.object_id) > 10000
    ORDER BY reads
    
    • 0

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何查看 Oracle 中的数据库列表?

    • 8 个回答
  • Marko Smith

    mysql innodb_buffer_pool_size 应该有多大?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    从 .frm 和 .ibd 文件恢复表?

    • 10 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    如何选择每组的第一行?

    • 6 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    bernd_k 什么时候应该使用唯一约束而不是唯一索引? 2011-01-05 02:32:27 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve