Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 我有一张有十把外键的桌子。如果我在所有十个键上都有索引,那么在插入时我会受到多大的影响?_Sql Server_Indexing - Fatal编程技术网

Sql server 我有一张有十把外键的桌子。如果我在所有十个键上都有索引,那么在插入时我会受到多大的影响?

Sql server 我有一张有十把外键的桌子。如果我在所有十个键上都有索引,那么在插入时我会受到多大的影响?,sql-server,indexing,Sql Server,Indexing,大家的共识似乎是所有外键都需要有索引。如果我遵守法律规定,我在插入时会招致多少开销 注: 假设数据库是一个良好的设计,并且所有连接都是合法的。 所有主键和外键均为Int类型。 有些表是查找表,记录少于10条,其大小不太可能增长。 它是一个OLTP数据库。 某些联接用于查找少于10条记录的表。 不需要在指向具有少量元素的查找表的外键上放置索引 不需要在指向具有少量元素的查找表的外键上放置索引 回答你的问题的唯一可能的方法是测试。例如,如果其中任何一个键的基数为10,则它们可能没有多大帮助。所以你有

大家的共识似乎是所有外键都需要有索引。如果我遵守法律规定,我在插入时会招致多少开销

注:

假设数据库是一个良好的设计,并且所有连接都是合法的。 所有主键和外键均为Int类型。 有些表是查找表,记录少于10条,其大小不太可能增长。 它是一个OLTP数据库。 某些联接用于查找少于10条记录的表。
不需要在指向具有少量元素的查找表的外键上放置索引

不需要在指向具有少量元素的查找表的外键上放置索引

回答你的问题的唯一可能的方法是测试。例如,如果其中任何一个键的基数为10,则它们可能没有多大帮助。所以你有一些工作要做测试。但它与您的表大小、键大小、绝对活动级别和CRUD元素的组合有很大关系。不要相信所有简单的答案

编辑:


如果您目前没有数据,因为这是初始设计,请仅从明显的索引开始,并根据测试根据需要添加其他索引。除非是一个变化不大的数据库,否则将它们全部添加是没有意义的。但如果它是只读的,就不会有太多的惩罚。另一条您尚未提供的信息。

回答您问题的唯一可能方法是测试。例如,如果其中任何一个键的基数为10,则它们可能没有多大帮助。所以你有一些工作要做测试。但它与您的表大小、键大小、绝对活动级别和CRUD元素的组合有很大关系。不要相信所有简单的答案

编辑:


如果您目前没有数据,因为这是初始设计,请仅从明显的索引开始,并根据测试根据需要添加其他索引。除非是一个变化不大的数据库,否则将它们全部添加是没有意义的。但如果它是只读的,就不会有太多的惩罚。您还没有提供的另一条信息。

是一个很好的示例列表,其中列出了使用索引的时间和类型。我认为你不应该接受法律,把所有的事情都编入索引。您需要定义将在查询联接中使用的内容,并相应地建立索引。

是一个适当的示例列表,其中列出了何时以及使用何种类型的索引。我认为你不应该接受法律,把所有的事情都编入索引。您需要定义将在查询联接和索引中使用的内容,因此插入操作会带来很大的性能损失,因为所有索引都需要更新。大致上,对于大表上的insert,您将导致一次磁盘写入,而对于表上的每个索引,平均会导致略多于一次的磁盘写入。每个索引叶节点都会发生写入操作,并且随着叶节点和不太常见的父节点的拆分,会不时发生一些额外的写入操作


每个表和索引写入也会产生日志流量。特别令人讨厌的惩罚是大容量插入的数据,因为插入大容量加载数据的表上的活动索引将针对每一行进行更新,并且这些更新不会被最低限度地记录下来。这将极大地破坏您的I/O,所有I/O都将是随机访问,而不是良好的顺序批量写入,还将产生大量的日志流量。

由于所有索引都需要更新,因此插入操作会造成严重的性能损失。大致上,对于大表上的insert,您将导致一次磁盘写入,而对于表上的每个索引,平均会导致略多于一次的磁盘写入。每个索引叶节点都会发生写入操作,并且随着叶节点和不太常见的父节点的拆分,会不时发生一些额外的写入操作


每个表和索引写入也会产生日志流量。特别令人讨厌的惩罚是大容量插入的数据,因为插入大容量加载数据的表上的活动索引将针对每一行进行更新,并且这些更新不会被最低限度地记录下来。这将极大地破坏您的I/O,所有I/O都将是随机访问,而不是良好的顺序批量写入,还将产生大量的日志流量。

这些字段将用于搜索和排序吗?如果是这样,索引可能是个好主意。知道的唯一方法是反复测试


编辑:查找表可能会被缓存,但这无助于对引用表进行搜索查询。您的数据表就是

这些字段将用于搜索和排序吗?如果是这样,索引可能是个好主意。知道的唯一方法是反复测试

编辑:查找表可能会被缓存,但这无助于对引用表进行搜索查询。您的数据表就是

大家的共识似乎是所有外键都需要有索引。多少爱 如果我遵守法律的规定,我会在插页上招致什么损失

有两种开销:引用表上的DML和引用表上的DML

引用的表应该有索引,否则将无法创建外键

引用表不能有索引。这将使插入到引用表中的速度稍微慢一点,并且不会影响插入到引用表中的速度

每当向引用表中插入行时,都会发生以下情况:

将根据外键检查该行,如此查询中所示:

SELECT  TOP 1 NULL
FROM    referenced ed
WHERE   ed.pk = @new_fk_value
SELECT  TOP 1 NULL
FROM    referencing ing
WHERE   ing.fk = @old_pk_value
将插入该行 行上的索引(如果有)已更新。 始终执行前两个步骤,步骤1通常再次使用引用表上的索引,如果没有此索引,则无法创建外键关系

步骤1是外键特有的唯一开销

步骤3的开销仅由索引存在的事实暗示。如果没有外键,情况也会完全相同

但是,如果不在引用表上定义索引,则引用表中的UPDATE和DELETE可能会慢得多,尤其是在引用表很大的情况下

无论何时从引用的表中删除,都会发生以下情况:

将根据外键检查行,如此查询中所示:

SELECT  TOP 1 NULL
FROM    referenced ed
WHERE   ed.pk = @new_fk_value
SELECT  TOP 1 NULL
FROM    referencing ing
WHERE   ing.fk = @old_pk_value
该行将被删除 行上的索引将被更新。 很容易看出,这个查询很可能受益于reference.fk上的索引

否则,即使要删除单个记录以检查约束,优化器也需要在整个表上构建一个哈希表

大家的共识似乎是所有外键都需要有索引。如果我遵守法律规定,我在插入时会招致多少开销

有两种开销:引用表上的DML和引用表上的DML

引用的表应该有索引,否则将无法创建外键

引用表不能有索引。这将使插入到引用表中的速度稍微慢一点,并且不会影响插入到引用表中的速度

每当向引用表中插入行时,都会发生以下情况:

将根据外键检查该行,如此查询中所示:

SELECT  TOP 1 NULL
FROM    referenced ed
WHERE   ed.pk = @new_fk_value
SELECT  TOP 1 NULL
FROM    referencing ing
WHERE   ing.fk = @old_pk_value
将插入该行 行上的索引(如果有)已更新。 始终执行前两个步骤,步骤1通常再次使用引用表上的索引,如果没有此索引,则无法创建外键关系

步骤1是外键特有的唯一开销

步骤3的开销仅由索引存在的事实暗示。如果没有外键,情况也会完全相同

但是,如果不在引用表上定义索引,则引用表中的UPDATE和DELETE可能会慢得多,尤其是在引用表很大的情况下

无论何时从引用的表中删除,都会发生以下情况:

将根据外键检查行,如此查询中所示:

SELECT  TOP 1 NULL
FROM    referenced ed
WHERE   ed.pk = @new_fk_value
SELECT  TOP 1 NULL
FROM    referencing ing
WHERE   ing.fk = @old_pk_value
该行将被删除 行上的索引将被更新。 很容易看出,这个查询很可能受益于reference.fk上的索引


否则,即使删除单个记录以检查约束,优化器也需要在整个表上构建哈希表。

了解影响的唯一方法是测试。答案可能会有很大的不同,这取决于您的系统倾向于在批量插入中插入大量数据,还是从用户界面一次插入一条记录。它还很大程度上取决于表的大小和索引的总数。测试是确定应该使用哪些索引的唯一方法。一般的经验法则是从索引外键字段和将在where子句中使用的字段开始。但这只是从哪里开始看你的系统,而不是最终的答案

我要说的是,我观察到,用户倾向于更容忍花在插入上的时间比花在查询系统上的时间更长一些。这一点尤其正确,因为高级管理人员倾向于进行更多的查询而不是数据输入,如果他们觉得自己的时间被浪费了,他们可能会变得暴躁,并有能力对此采取行动

在一个新系统中,您需要在系统实现时的预期容量下生成测试记录。如果您不这样做,那么您将发现在同一个测试台上正常工作的查询和设计可能会很糟糕,因为实际用户同时对大型表执行多个操作。重构一个在设计中没有考虑和测试性能的数据库一点也不好玩。收回生产更改并不是一件有趣的事,因为查询所花费的时间比超时设置要长,因为开发人员没有针对真实卷进行测试,或者在新项目中,没有针对预期的v 专栏


SQL Server有一些工具可以帮助您确定最佳索引。使用索引向导和执行计划查看需要索引的位置。在字段上放置索引并测试插入,以查看是否有负面影响。没有一个正确的答案。很可能在数据库的整个生命周期内都不会保持相同的答案。

了解影响的唯一方法是测试。答案可能会有很大的不同,这取决于您的系统倾向于在批量插入中插入大量数据,还是从用户界面一次插入一条记录。它还很大程度上取决于表的大小和索引的总数。测试是确定应该使用哪些索引的唯一方法。一般的经验法则是从索引外键字段和将在where子句中使用的字段开始。但这只是从哪里开始看你的系统,而不是最终的答案

我要说的是,我观察到,用户倾向于更容忍花在插入上的时间比花在查询系统上的时间更长一些。这一点尤其正确,因为高级管理人员倾向于进行更多的查询而不是数据输入,如果他们觉得自己的时间被浪费了,他们可能会变得暴躁,并有能力对此采取行动

在一个新系统中,您需要在系统实现时的预期容量下生成测试记录。如果您不这样做,那么您将发现在同一个测试台上正常工作的查询和设计可能会很糟糕,因为实际用户同时对大型表执行多个操作。重构一个在设计中没有考虑和测试性能的数据库一点也不好玩。收回生产更改并不是一件有趣的事,因为查询所需的时间比超时设置要长,因为开发人员没有针对真实卷或新项目的预期卷进行测试

SQL Server有一些工具可以帮助您确定最佳索引。使用索引向导和执行计划查看需要索引的位置。在字段上放置索引并测试插入,以查看是否有负面影响。没有一个正确的答案。在数据库的整个生命周期内,它都可能不会保持相同的答案。

插入/更新/删除总是命中索引并写入索引。Select有时会点击索引进行读取,具体取决于查询优化器的分析或最佳猜测。如果不需要索引来加快读取速度,例如如果列只有少量的潜在值,那么就将其删除

如果子表中有10亿行,并且希望删除其中1亿行,因为您要从父表中删除一行,而该行是所有1亿个子行的父行,那么拥有索引只会降低整个操作的速度,因为系统也必须从索引中删除,但不会加快操作速度,因为系统不会使用索引来加快选择要删除的行的速度。

Insert/update/delete始终命中索引并写入索引。Select有时会点击索引进行读取,具体取决于查询优化器的分析或最佳猜测。如果不需要索引来加快读取速度,例如如果列只有少量的潜在值,那么就将其删除


如果子表中有10亿行,并且希望删除其中1亿行,因为您要从父表中删除一行,而该行是所有1亿个子行的父行,那么拥有索引只会降低整个操作的速度,因为系统也必须从索引中删除,但不会加快操作速度,因为系统不会使用索引加快选择要删除的行的速度。

谢谢大家的输入

根据您的反馈,我想我会为所有外键添加索引,除了那些指向包含少量不太可能更改的记录的查找表的外键。这将把所需外键索引的数量从10个减少到5个,减半


如果有人有进一步的见解,请随时发布新的答案。我还有一些选票

谢谢大家的意见

根据您的反馈,我想我会为所有外键添加索引,除了那些指向包含少量不太可能更改的记录的查找表的外键。这将把所需外键索引的数量从10个减少到5个,减半


如果有人有进一步的见解,请随时发布新的答案。我还有一些选票

我知道性能是一个关键问题


IMO,您应该考虑没有索引,因此没有OLTP数据上的FK的后果。在这样的系统上,您可能会遇到数据完整性问题。

我知道性能是一个关键问题

IMO,您应该考虑没有索引,因此没有OLTP数据上的FK的后果。您可能会遇到数据完整性问题



在这样一个系统上起诉。

重复:我所追求的是性能惩罚,而不是公认的做法。社区中一些人的直接答案总是索引。然而,现在有些人说,在现实世界中,他们并不总是这样。是的,我。但是,如果有人试图删除我们的子表中有1亿行的查找表行,而您在另一篇文章中询问了性能问题,我们接受了这种折衷,不是吗?任何关于数据库设计的问题,包括“从不”或“始终”这几个词,都可能会产生这种问题。我问过,但这个问题已经过时了。我想我可以等一会儿。社区不喜欢在同一个愚蠢的帖子社区中出现太多问题。重复:我想要的是表现惩罚,而不是公认的做法。社区中一些人的直接答案总是索引。然而,现在有些人说,在现实世界中,他们并不总是这样。是的,我。但是,如果有人试图删除我们的子表中有1亿行的查找表行,而您在另一篇文章中询问了性能问题,我们接受了这种折衷,不是吗?任何关于数据库设计的问题,包括“从不”或“始终”这几个词,都可能会产生这种问题。我问过,但这个问题已经过时了。我想我可以等一会儿。社区不喜欢在同一个post社区中出现太多问题……但是索引用于子表中的行,用于DRI检查,以处理查找行删除etc@Robert当前位置谢谢,但是birdlips首先回答了他的文章链接,但在很多情况下这是错误的答案。如果您想要索引键之外的数据,基数10通常会给您提供表扫描。除非您有时需要从包含少量元素的查找表中删除。@alexkuznetsov:假设少量元素实际上很小,例如10-20,这不是真的。当然,这是假设从小型枚举表中删除是一种非常罕见的情况,仅在数据库升级时发生,即不进行交互…但是索引用于子表中的行,用于DRI检查,以处理查找行删除etc@Robert:谢谢,但是birdlips的文章首先给出了答案,但在很多情况下这是错误的答案。如果您想要索引键之外的数据,基数10通常会给您提供表扫描。除非您有时需要从包含少量元素的查找表中删除。@alexkuznetsov:假设少量元素实际上很小,例如10-20,这不是真的。当然,这是假设从一个小枚举表中删除一个非常罕见的事件,它只发生在数据库升级时间,即不是交互式的。相关的位是:主键/外键关系中的更新或删除操作。其他相关的位是考虑的索引,而不是创建的索引。相关的问题是:主键/外键关系中的更新或删除操作,其他相关的位是考虑的索引,而不是创建的索引。回答这个问题需要更多的参与。老实说,我不太喜欢这种测试。它需要生成大量的测试数据,根据定义,这些数据将不能代表我们的实际使用模式,因为这是一个新项目,我们不知道。您的使用模式和表大小在不同的时间具有不同的特征,因此需要对问题给出不同的答案。对于您目前没有的数据配置文件,测试没有太多意义——测试现有的配置文件已经足够具有挑战性了。如果你不想测试,你将很难设计起作用的数据库。现在有一个很好的问题要问你。。。我想你表达了我的观点。如果索引需要根据实际使用模式进行调整,那么预先测试还为时过早。老实说,我不太喜欢这种测试。它需要生成大量的测试数据,根据定义,这些数据将不能代表我们的实际使用模式,因为这是一个新项目,我们不知道。您的使用模式和表大小在不同的时间具有不同的特征,因此需要对问题给出不同的答案。对于您目前没有的数据配置文件,测试没有太多意义——测试现有的配置文件已经足够具有挑战性了。如果你不想测试,你将很难设计起作用的数据库。现在有一个很好的问题要问你。。。我想你表达了我的观点。如果索引需要根据实际使用模式进行调整,那么预先测试是不成熟的?在我想到的连接中,被引用的表的记录不会超过10个

rds。@Robert:如果从引用表中删除某些内容,如果引用表上没有索引,则删除速度可能会非常慢。被引用表中的INSERT完全不受外键的影响。引用表中的INSERT受其上的索引的影响程度与普通表上的索引的影响程度相同。假设引用表是查阅表,则不太可能进行此类删除,因为查阅表中的记录是应用程序设计的一部分。如果我们要删除其中一条记录,则可以接受一些时间延迟。我假设引用的表是具有主键的表?在我想到的联接中,引用表中的记录不会超过10条。@Robert:如果从引用表中删除某些内容,如果在引用表上没有索引,这可能会非常慢。被引用表中的INSERT完全不受外键的影响。引用表中的INSERT受其上的索引的影响程度与普通表上的索引的影响程度相同。假设引用表是查阅表,则不太可能进行此类删除,因为查阅表中的记录是应用程序设计的一部分。如果我们要删除其中一条记录,则可以接受一些时间延迟。正确规范化数据库中的OLTP应该在基于插入的模型上工作,而不是在基于更新的模型上进行更改。我同意这对批量插入是一个巨大的惩罚,但是如果我们一次只插入一个/小的行集,如何评估对OLTP数据库的影响呢?如果没有某种形式的多用户负载测试,我认为没有好的方法。但是,如果计算主键,一个表11上的十个索引对我来说似乎仍然过多。正确规范化的数据库中的OLTP应该使用基于插入的模型,而不是基于更新的模型进行更改。我同意这对批量插入是一个巨大的惩罚,但是如果我们一次只插入一个/小的行集,如何评估对OLTP数据库的影响呢?如果没有某种形式的多用户负载测试,我认为没有好的方法。但是如果你计算主键的话,一个表上的十个索引对我来说仍然是多余的。外键确实包含到查找表的约束连接。这对于引用完整性应该足够了。外键确实包含到查找表的约束联接。这对于引用完整性应该足够了。它们可能用于搜索和排序,但鉴于其大小,查找表仍将被缓存。它们可能用于搜索和排序,但鉴于其大小,查找表仍将被缓存。父表不太可能更改,除非我们重新设计。确定。但关键是,一个列上具有低基数和少量不同元素的索引不会有助于提高读取性能,因为优化器将跳过索引,直接进行表扫描;此外,它还会妨碍插入/更新/删除性能,因为现在数据库必须进行双重写入才能同时更改表中的数据和索引中的数据。除非重新设计,否则父表不太可能更改。确定。但关键是,一个列上具有低基数和少量不同元素的索引不会有助于提高读取性能,因为优化器将跳过索引,直接进行表扫描;此外,它还将阻碍插入/更新/删除性能,因为现在数据库必须进行双重写入才能同时更改表中的数据和索引中的数据。