什么是SQL Server的理想索引策略?

时间:2011-03-01 08:57:18

标签: sql sql-server

我和朋友正在开发一个使用SQL Server的新项目。在我之前完成项目的SQL中,我总是将索引放在JOIN或WHERE中使用的任何字段上。

我的朋友只有在有性能需求时才添加它们。这个想法是维护索引需要付出代价,并且您希望确保支付这笔费用。可以公平地说,有些查询不会经常使用,而且有些表会比其他表更加积极地添加。

因此,我正在寻找有关数据库索引“最佳实践”的建议。什么对你有用?

7 个答案:

答案 0 :(得分:4)

我会尝试遵循这些准则:

  • 始终拥有良好主要/群集密钥 - 通常为INT IDENTITY - 避免使用GUID或大型复合PK / CK。精心挑选的PK / CK将大大有助于提升整体表现。要彻底了解原因,请阅读所有Kimberly Tripp的blog posts on clustering key选项。

  • 始终索引所有外键列 - 单独或与其他有意义的列一起索引;这有助于加入性能

  • 除此之外:少就是!如果绝对必须,只添加索引 - 观察您的系统,分析您的数据负载,查看性能,微调,再次测量。如果索引有帮助 - 保持它;如果索引没有被使用 - 扔掉它

  • 使用手头的DMV(missing index DMV, and the unused indices DMV)来了解哪些指数可能有所帮助,以及哪些指数根本没有被使用......

答案 1 :(得分:3)

我个人偏好采用主动式方法:根据您的查询,在需要时添加索引。正如您所说,在JOIN或WHERE中涉及的字段。每个索引都会加速读取查询,但会降低写入速度(因为每次写入都需要更新索引)。因此,对于写密集型表,可能需要其他解决方案(数据仓库,复制......)。

另一种方法,只添加性能需要它们的索引,只有在你进行主动监控时才有效,但即便如此也有几个缺点

  • 您必须向遇到性能问题的表添加索引。在添加索引时,您的表被锁定 - 这是一个使用频繁的表!
  • 通常在测试时,测试数据比应用程序中的实际数据小几个数量级。瓶颈可能会被忽视。

答案 2 :(得分:2)

您希望仅将它们放在那些对它们进行大量查询的列或列组上。您可以从SQL Server获取大量统计信息,以查看针对您的表运行的查询,SQL Server甚至会建议您没有它们的索引。

这是一个很好的链接,其中包含一些有用的信息和其他指向良好信息的链接。 SQL Server Index Checklist and tips

答案 3 :(得分:1)

设计索引时,请遵循以下准则:

  
      
  • 在包含大量行的表上使用索引   查询的WHERE子句或表   连接,以及ORDER BY中使用的列   和GROUP BY查询。
  •   
  • 避免在频繁更新的列上不经常使用的索引。在   另外,避免使用多个索引   经常更新的表。   否则,你会不必要地增加   您的插入和更新时间   查询。为了提高性能,   最小化的总宽度   索引列。
  •   
  • 适当地使用聚簇和非聚簇索引。明白了   每个目的,选择正确   为您的方案键入。
  •   
  • 使用覆盖索引可以减少频繁的查询执行时间   用过的陈述。覆盖指数是a   具有所有的非聚集索引   WHERE子句中的列   并在查询列选择中。
  •   

根据

http://msdn.microsoft.com/en-us/library/ff650692.aspx

答案 4 :(得分:1)

您的问题没有简单的答案。这一切都归结为表格的使用。监视表的使用将告诉您该怎么做。

答案 5 :(得分:1)

select * from sys.dm_db_missing_index_details

了解您的动态管理视图

然后从这个URL中使用此sproc http://www.sqlservercentral.com/scripts/Index+Management/63937/

另外.. homedude所说的'覆盖索引'确保你理解覆盖索引(SQL 2000)和带有INCLUDE子句的索引(SQL 2005及更新版本)之间的区别

答案 6 :(得分:1)

索引最好放在尽可能唯一的值。例如,无用在列上放置一个索引,其中该列的50%为值'A',另一列的50%具有值'B'。

这样,在选择正确的值之前,该表将扫描至少50%的记录

所以最佳做法是在最独特的列上放置一个索引,而只放置那些用于选择查询的列。

示例:如果您要为典型的“登录”创建选择,则会在“用户名”列上放置索引,因为您确保用户名是唯一的。