索引,主键,唯一键的影响的详细信息

时间:2010-01-14 18:10:38

标签: sql performance indexing primary-key

我喜欢认为我知道理论,但我在现实世界中优化数据库的经验很少。 我想知道观点,想法或经验。

让我们想象一下这样的场景:

表A. 键:c1,c2,c3,c4 指数:c7,c3,c2

表B. 键:c1,c2,c3,c4 指数:c1,c5

所有都是非群集的。 这些表有40多个字段。 它们每天晚上都会被喂食,并且在白天会有一些更新。

表A,如果更多的查询受益于Key而不是Index,那么该指数可能会产生负面影响吗? 因为插入/删除必须更新2个索引而不是1。

表B,索引处有一个额外的字段,而不是密钥。

可以使用c1,c5查询

从这把钥匙中获益?: 密钥:c1,c2,c3,c4,c5

这样可以降低指数。

字段的顺序有什么影响? 键:c1,c2,c3 关键:c3,c1,c2

我的典型场景是process_date,client_number,operation。 它每天都会提供大量数据(process_date)。

4 个答案:

答案 0 :(得分:1)

如果更多的查询受益于Key而不是Index,那么该指数是否会对此产生负面影响?

但是...

您必须实际测量实际工作量,看看是否属实。从纯粹的理论角度来看很难预测。可能,但很难。

使用c1,c5查询可以从此密钥中受益吗?:密钥:c1,c2,c3,c4,c5

很少。查询算法很少使用密钥或索引的一部分。它通常是全有或全无。如果不能使用整个键(或索引),则不使用它。

很容易获得查询执行计划并得到这个问题的明确答案。

学会获得执行计划并实际获得它们。

字段的顺序有什么影响?键:c1,c2,c3键:c3,c1,c2

几乎没有任何影响。在某些数据库中,如果省略ORDER BY子句,它可以更改行的显示方式。在其他数据库中,它没有影响,因为物理行和键索引的顺序是分开的。

您可以轻松删除并重新创建索引,检查执行计划,并查看具有的影响(如果有)。

唯一可以确定的方法是获取执行计划并查看它们。

答案 1 :(得分:1)

如果您正在尝试优化索引策略,则可以运行Database Tuning Advisor或查询sys.dm_db_index_usage_stats以了解索引的使用方式。 (重新启动SQL Server进程时会清除这些统计信息。)

在回答第一个问题时,索引总是会对写入性能产生负面影响,因此清除未使用的索引会很有用。但要确保它们真的没用过。

在回答第二个问题时,删除索引不太可能提高查询性能,实际上可能会降低它,因为索引覆盖了最少列数的查询。如果通过“使用c1,c5”意味着那些是唯一涉及的两列,那么删除索引可能会略微降低性能。如果查询选择的列数多于索引中的列数,那么如果索引被使用,则索引必须连接到表中,因此如果删除它,则不太可能影响性能。唯一可以确定的方法是分析两种方案的查询成本。

答案 2 :(得分:1)

  

如果更多查询受益于Key比   指数,指数可能会影响   负?因为插入/删除有   更新2个索引而不是1。

非聚集索引对插入/更新/删除性能有负面影响。选择的性能提升通常会抵消负面影响。

  

使用c1,c5查询可以获益   从这把钥匙?:钥匙:c1,c2,c3,c4,   C5

是的,如果只有几行共享相同的c1,那么索引将非常有效。

  

顺序有什么影响   有哪些领域?键:c1,c2,c3键:c3,   c1,c2

顺序对于过滤和排序都很重要。 (c1,c2)上的索引可用于where c1 = 1where c1 = 1 and c2 = 1,但不能用于where c2 = 1。同样,它有助于order by c1,但不会与order by c2有关。

答案 3 :(得分:1)

索引肯定会对表更改(插入,更新或删除)产生负面影响。除非您有大量不必要的索引或者您的系统具有极高的数据更改率,否则一个或两个额外的索引不太可能成为问题。不要只是无条件地将索引放在表上,但通常不需要进行广泛的分析来试图避免使用索引。

表上的键应该是唯一标识行的最小列集。它不应包含其他列。例如,如果我有一个唯一的电子邮件地址表,而我的密钥在email_address上,那么我只能为“me@here.com”添加一行。如果我现在将描述添加到密钥中,因为我在很多查询中使用了描述,然后突然我可以:“me@here.com”,“描述#1”和“me@here.com”,“描述#2" 。你的数据不再受到适当的约束,你的手上就会出现大麻烦。

根据您使用的查询,密钥中列的排序可能会产生非常大的影响。例如,如果您正在寻找基于c1,c2的行,那么c1,c2,c3的键将非常有用。如果您的密钥是c1,c3,c2那么它就没用了。

想象一下,我想让你看一下电话簿,找到姓氏以“TO”开头的所有人。这是一个非常简单的请求。现在,如果名字是由姓氏的第一个字母后面跟姓氏的第三个字母排序的呢?找到以“TO”开头的名字将是非常困难和耗时的。