1
368
一
(即使
很可能您的性能问题存在于其他地方,例如没有正确索引候选密钥或外键。9张桌子是相当多的加入,所以经济放缓几乎可以在任何地方。如果您发布您的模式,我们可能可以提供更多的详细信息。 编辑:
再仔细想想,我可以想到一种情况,在这种情况下
举个例子:
如果运行此命令并查看执行计划,您将看到
你可以看到同样的效果,用你最喜欢的编程语言编写一个程序,在一个包含5个元素的列表上执行大量的查找,而不是一个包含5个元素的哈希表。由于大小的关系,哈希表的版本实际上较慢。但是增加到50个元素,或者5000个元素,列表版本就会变慢,因为哈希表是o(n)对o(1)。
但将此查询更改为
因此,结论或多或少是我在上面提到的;这几乎肯定是一个索引或索引覆盖率问题,可能与一个或多个非常小的表结合在一起。在这些情况下,SQL Server
可以
有时选择一个更糟糕的执行计划
|
2
104
有一个重要的场景可以导致外部连接比内部连接更快,而内部连接尚未讨论。
使用外部联接时,如果联接列是外部表的主键,并且没有从外部表中选择任何列,优化器总是可以从执行计划中删除外部联接表。例如
对于内部连接,不一定也是这样:
如果a.key是引用b.key的可空外键,那么优化器不能从计划中删除b,因为它必须确认每一行都存在b行。 如果a.key是引用b.key的强制外键,那么优化器可以从计划中删除b,因为约束保证了行的存在。但仅仅因为优化器可以从计划中删除表,并不意味着它会这样做。SQL Server 2008 R2不会从计划中删除B。甲骨文10确实从计划中删除了b。在这种情况下,很容易看出外部连接将如何在sql server上执行内部连接。 这是一个很小的示例,对于独立查询不实用。如果你不需要的话,为什么要加入一张桌子? 但在设计视图时,这可能是一个非常重要的设计考虑因素。通常会构建一个“do everything”视图,将用户可能需要的与中心表相关的所有内容连接起来。(特别是当有天真的用户执行不理解关系模型的特殊查询时)视图可能包含许多表中的所有相关列。但最终用户可能只访问视图中表子集中的列。如果表与外部联接联接,那么优化器可以(并且确实)从计划中删除不需要的表。 确保使用外部连接的视图给出正确的结果是至关重要的。正如aaronaught所说-你不能盲目地用外部连接代替内部连接,并期望得到相同的结果。但有时在使用视图时,由于性能原因,它会很有用。 最后一个注意事项-我没有根据上述内容测试对性能的影响,但在理论上,如果您还将条件“foreign_key>不为空”添加到where子句中,则应该能够安全地将内部联接替换为外部联接。 |
3
21
如果每件事都能正常工作,那么它就不应该正常工作,但是我们都知道每件事都不能正常工作,尤其是在查询优化器、查询计划缓存和统计方面。 首先,我建议重建索引和统计数据,然后清除查询计划缓存,以确保这不会把事情搞砸。不过,即使这样,我也遇到过问题。 我经历过一些左连接比内部连接快的情况。 根本原因是: 如果您有两个表,并且您使用索引(在两个表上)连接到一列上。 无论您是否循环遍历表1上的索引项并与表2上的索引匹配,内部联接都将产生相同的结果,就像您执行相反的操作:循环遍历表2上的索引项并与表1中的索引匹配。 问题是当您有误导性的统计信息时,查询优化器将使用索引的统计信息来查找具有最少匹配项的表(基于您的其他条件)。 如果有两个表,每个表中有100万行,那么在表1中有10行匹配,在表2中有10万行匹配。最好的方法是对表1进行索引扫描,并在表2中匹配10次。相反,索引扫描会循环超过100000行,并尝试匹配100000次,但只有10次成功。因此,如果统计数据不正确,优化器可能会选择错误的表和索引进行循环。 如果优化器选择按编写顺序优化左连接,那么它的性能将优于内部连接。 但是,优化器也可以将左连接次优优化为左半连接。要使它选择您想要的,您可以使用force order提示。 |
4
16
使用
如果
不知道这是否回答了您的问题,但我曾经参与过一个项目,该项目的特点是进行计算的高度复杂的查询,这完全扰乱了优化器。我们有这样的案例
|
5
7
已经在左外部连接和内部连接之间做了一些比较,但找不到一致性差异。有很多变数。我正在处理一个包含数千个表的报表数据库,其中许多表包含大量字段,随着时间的推移有许多更改(供应商版本和本地工作流)。不可能创建覆盖索引的所有组合以满足如此广泛的查询和处理历史数据的需要。已经看到内部查询会扼杀服务器性能,因为两个大型(数百万到千万行)表是内部连接的,它们都会拉取大量字段,并且不存在覆盖索引。 不过,最大的问题似乎并没有出现在上述讨论中。也许您的数据库是精心设计的触发器和精心设计的事务处理,以确保良好的数据。我的经常有空值,它们不是预期的。是的,表定义不能强制使用空值,但在我的环境中这不是一个选项。 所以问题是…您是否只为速度而设计查询?对于每分钟运行数千次相同代码的事务处理来说,速度是一个更高的优先级。或者你会追求左外连接所提供的准确性。请记住,内部联接必须在两边找到匹配项,因此意外的空值不仅会从两个表中删除数据,而且可能会删除整行信息。它发生得很好,没有错误信息。 您可以非常快地获得90%的所需数据,而不发现内部连接已悄悄删除了信息。有时内部连接可能更快,但我不相信任何人做出这种假设,除非他们已经审查了执行计划。速度很重要,但准确度更重要。 |
6
5
性能问题更可能是因为连接的数量以及连接的列是否有索引。 最坏的情况是,您很容易为每个连接执行9次整表扫描。 |
7
4
外部连接在视图中使用时可以提供优异的性能。 假设您有一个查询涉及一个视图,该视图由10个连接在一起的表组成。假设您的查询只使用了这10个表中的3个表中的列。 如果那10张桌子 内部连接 这样,即使查询本身不需要十分之七的表,查询优化器也必须将它们全部联接起来。这是因为内部连接本身可能会过滤掉数据,使它们成为计算所必需的。 如果那10张桌子 外接 相反,查询优化器将只实际连接必要的查询:在本例中,10个查询优化器中的3个。这是因为连接本身不再过滤数据,因此可以跳过未使用的连接。 来源: http://www.sqlservercentral.com/blogs/sql_coach/2010/07/29/poor-little-misunderstood-views/ |
8
1
在检查内部连接是否比左连接快时,我在sql server中发现了一些有趣的东西。 如果不包括左联接表的项,则在select语句中,左联接将比具有内部联接的同一查询快。 如果在select语句中包含左联接表,则具有相同查询的内部联接等于或快于左联接。 |
S. Jacson · 任意两台发电机的速度差(内置功能) 2 年前 |
Sadeq Dousti · 相当于“嵌套删除”的执行性能SQL查询 2 年前 |
Prince · 复制大型文件需要更多时间 2 年前 |
Sagar · 为什么在循环之外声明变量会更快? 2 年前 |
seco · 如何在不挂起页面的情况下加载JS 2 年前 |