是否应该将索引放在正在更新的SQL表上?

是否应该将索引放在正在更新的SQL表上?,sql,sql-server,Sql,Sql Server,我们每天晚上都会制作一张工作表,上面有超过一百万条记录。 这个过程每晚大约需要3小时才能完成。在过程中首先将所有数据插入表中。然后我们对表进行大量更新 例如: Update a Set a.Field1 = b.Field1 From WorkingTable as a JOIN Table2 as b Where a.ID = b.ID 此时,我们没有为工作表分配任何索引或键。如果我们将索引或键分配给工作表,它会运行得更快吗 谢谢它可能会跑得更快,也可能不会。索引存在并不能保证它会被使用 假

我们每天晚上都会制作一张工作表,上面有超过一百万条记录。 这个过程每晚大约需要3小时才能完成。在
过程中
首先将所有数据插入表中。然后我们对表进行大量更新

例如:

Update a
Set a.Field1 = b.Field1
From WorkingTable as a JOIN Table2 as b
Where a.ID = b.ID
此时,我们没有为
工作表
分配任何索引或键。如果我们将
索引
分配给
工作表
,它会运行得更快吗


谢谢

它可能会跑得更快,也可能不会。索引存在并不能保证它会被使用

假设示例中的表2只包含两条记录。那么dbms使用WorkingTable.id上的索引来快速查找这两条记录肯定是有意义的

现在让我们假设table2包含的记录是工作表的10000倍。然后,简单地逐个检查工作表记录并查找Table2.id的索引可能更有意义。那么,您的工作表中就不需要索引了

话虽如此:不能保证指数会加速事情的发展,但它可能会。如果没有,也没有造成任何伤害。正如Luc M在对您的请求的评论中所说的那样:当需要关心索引时,insert和delete会变慢(但据我所知,您已经完成了insert)。更新和选择可以从索引中获益


因此,是的,使用索引(在WorkingTable.id上为您的示例)并查看它们是否有帮助。

此顺序应能提高性能(您需要进行精确计时以确定):

  • 加载工作台
  • 在工作表的ID上创建索引
  • 在表2的ID上创建索引(如果尚未创建)
  • 做你的更新
  • 要准确测量定时(不要在生产服务器上执行此操作!):


    要回答这个问题,首先需要知道密钥和索引在SQLServer中是如何工作的

    默认情况下,主键是聚集唯一索引。虽然这确实会降低插入记录的速度,但速度应该是最小的。性能的真正下降通常来自SQL查询或DML语句中导致表扫描的
    where
    子句。如果在初始创建后更新了足够多的记录,那么在
    id
    列上添加主键或聚集唯一索引将是一个性能胜利

    实际上,使用主键或索引的决定可以归结为以下问题:

    谁生成“id”?加载数据的应用程序还是数据库

    如果加载数据的应用程序生成“id”值,那么在该列上添加聚集索引就足够了

    CREATE CLUSTERED INDEX IDX_WorkTable_ID 
    ON dbo.WorkTable (ID); 
    
    如果数据库正在生成这些值,只需将“id”列设为
    int
    类型的主键即可:

    ALTER TABLE [WorkTable] ADD ID INT IDENTITY(1,1);
    
    使用主键插入、更新和删除仍然非常快

    发件人:

    除了少数例外,每个表都应该有一个聚集索引。除了提高查询性能外,还可以根据需要重建或重新组织聚集索引以控制表碎片。还可以在视图上创建聚集索引

    相关的:

    如果需要更新索引列的值,索引可能会影响性能。对这些列值的每次更新都会导致SQL server重新生成该索引

    与任何性能增强一样,测试它。证据就在布丁里

    结论

  • 编写SQL以避免表扫描
  • 不要在值已更新的列上创建索引,也不要在另一个查询或语句的
    where
    子句中为不需要的列创建索引
  • 避免不必要的连接

  • 这些是任何SQL查询的基本性能准则。

    yes使用
    ID上的主键
    我会尝试、测量和比较。我相信没有确切的答案。似乎
    a.ID
    (最好是唯一的)上的索引可能会有所帮助。通常,表上的索引的插入/删除速度较慢。更新速度取决于索引和WHERE子句。在这种情况下,总是添加索引不是更好吗?然后,SQL可以决定是否使用它(只要查询写得不差,SQL很少会建议错误的查询计划)@Charleh:这就是我要说的。不能保证索引会被使用,但为什么不试试呢?(只有当列上的索引本身将被更新时,这些更新才会减慢。否则,更新会加快或保持不变。不会造成任何伤害。)
    ALTER TABLE [WorkTable] ADD ID INT IDENTITY(1,1);