链表上的SQL索引策略

时间:2013-10-23 11:49:56

标签: sql indexing

我经常发现自己在创建'链接表'。例如,下表将用户记录映射到事件记录。

CREATE TABLE [dbo].[EventLog](
    [EventId] [int] NOT NULL,
    [UserId] [int] NOT NULL,
    [Time] [datetime] NOT NULL,
    [Timestamp] [timestamp] NOT NULL
)

出于此问题的目的,请假设EventId和UserId的组合是唯一的,并且相关数据库是MS SQL Server 2008安装。

我遇到的问题是我无法确定如何将这些表编入索引。例如,我可能希望列出特定事件的所有用户,或者我可能希望列出特定用户的所有事件,或者可能要检索特定的EventId / UserId记录。我考虑过的索引选项包括:

  1. 在EventId和UserId上创建复合主键(但是我 理解当UserId访问它时,索引将没有用处 自己的)。
  2. 在EventId和UserId上创建复合主键并添加a UserId的补充索引。
  3. 在EventId上创建主键并在其上创建补充索引 用户ID。
  4. 任何建议都将受到赞赏。

2 个答案:

答案 0 :(得分:1)

指数旨在解决性能问题。如果你还没有遇到这样的问题并且无法确切地知道你将面临哪些麻烦,那么就不应该创建索引。指数非常昂贵。因为它不仅占用磁盘空间,而且还会导致写入或修改数据的开销。因此,您必须清楚地了解通过创建索引确定的具体性能问题。所以你可以理解创建它的必要性。

答案 1 :(得分:1)

您的问题的答案取决于几个方面。

  1. 这取决于您要使用的DBMS。有些人更喜欢单列索引(如Postgresql),有些可以更多地利用多列索引(如Oracle)。有些人可以完全从覆盖索引(如sqlite)回答查询,其他人不能并且最终必须阅读实际表的页面(再次,如postgres)。

  2. 这取决于您要回答的查询。例如,您是否向两个方向导航,即您是否加入了两个Id列?

  3. 这也取决于数据修改的空间和处理时间要求。请记住,索引通常比它们索引的实际表大,并且更新索引通常比更新基础表更昂贵。

  4. 编辑:

    当你的概念模型在两个实体E1和E2之间具有多对多关系R时,即R的逻辑语义要么“相关”要么“不相关”,要么总是声明组合初级R的关键。这将创建一个唯一的索引。然而,主要动机是数据一致性,而不是查询优化,即:

    CREATE TABLE [dbo].[EventLog](
        [EventId] [int] NOT NULL,
        [UserId] [int] NOT NULL,
        [Time] [datetime] NOT NULL,
        [Timestamp] [timestamp] NOT NULL,
        PRIMARY KEY([EventId],[UserId])