【问题标题】:Is there an alternative to joins to increase performance?有没有替代联接来提高性能?
【发布时间】:2010-07-24 06:51:38
【问题描述】:

是否有替代联接来提高性能?

编辑(gbn):与join-or-correlated-subquery-with-exists-clause-which-one-is-better相关


为什么没有人提到嵌套循环连接?

【问题讨论】:

  • 您有什么特别的想法吗?
  • 没有。只是一个一般性的问题,这样我就可以在编写连接语句时提高我的技能
  • 那么您需要提供更多详细信息,关于您认为标准的内容。您是否正在寻找联接的替代方法或编写联接的替代方法?您的问题不是很集中,也不是很清楚。

标签: sql sql-server join


【解决方案1】:

不是 JOIN 的“替代”方式,而是提高 JOIN 性能的提示:在 SQL Server 中,很多人不知道的是,您应该始终将非聚集索引放在外键列上。一些人认为 SQL Server 会自动执行此操作 - 它不会。

因此,如果您有一个表Customer,它可能有一个类似于CustomerID 的主键。 SQL Server 会自动为其添加索引。

但是,如果您有一个与Customer 有外键关系的表Order,则默认情况下Order.CustomerID 列上没有索引。但是这样的索引对于连接和查找非常有用和有帮助,所以这是我一直推荐的最佳做法:在表中的所有外键列上放置索引。

【讨论】:

  • 这真是太神奇了,我不知道外键默认没有索引。这将我的查询性能提高了 100 倍,加入 5 个表,结果约为 7500 行! (之前是 5.5 秒,现在是 55 毫秒)+1
【解决方案2】:

你的其他问题

select * 
from ContactInformation c 
where exists (select * from Department d where d.Id = c.DepartmentId )

select * 
from ContactInformation c 
inner join Department d on c.DepartmentId = d.Id  

如果您想要两个表的输出,那么您可以选择 JOIN 以外的选项。这里是第二个查询。

如果很慢,一般情况下:

  • 您有主键/索引吗?
  • 一致的数据类型(DepartmentId/id 列)
  • 不要使用 SELECT *

【讨论】:

  • 关于不使用 SELECT * 的好提示,我不再使用它,只选择您需要的字段,这有时可以大大加快查询速度。
【解决方案3】:

降低连接性能的策略:

  • 索引
  • 非规范化
  • 缓存结果
  • 使用 NoSQL 数据库(无 SQL = 无联接,q.e.d.)

所有这些策略都针对特定查询进行了优化。您无法制定可以改进所有个查询的通用解决方案。

【讨论】:

    【解决方案4】:

    如果您想要/可以读取未提交的记录,则在连接上使用 (NOLOCK) 可能会提高性能。 When should you use "with (nolock)"

    【讨论】:

    • stackoverflow.com/questions/1452996/… Nolock 不应一直使用或用于所有表。用于旧/临时/存档表实际上是一个好主意,而不是日常事务表。利用索引表/视图、分区表、游标等。
    【解决方案5】:

    从句法上讲,没有其他方法,只有一些技术可以帮助您提高海量数据的查询性能:

    • 如果适用且查询返回的列数不多,您可以使用 INTERSECT、EXCEPT 或 UNION
    • 如果查询非常复杂并且在大量数据上包含许多步骤,请使用临时表分而治之。
    • 如果查询返回到显示一些可能是昨天数据图像的信息的报告,您可以使用 sql server 代理作业来计算结果并将结果保存在一个表中,以用作报告而不是查询或作为替代使用索引视图来获取结果。
    • 如果某些信息(例如表中的行数)需要很长时间才能获取,您可以使用表的元数据表来获取此类信息。这不仅适用于表中的行数。您可以获得元数据中的大量信息,无需计算。(保持联系this site

    【讨论】:

      【解决方案6】:

      关系数据库经过优化以使用联接,因此在大多数情况下,使用联接是您能做的最重要的事情。

      如果您的查询很慢,则需要对其进行优化 - 也许您缺少一两个索引,也许您可​​以重写 where 子句以减少返回的行数。

      您可以使用sub-queriestemp tables,但连接可能仍然是最快的。您必须在自己的环境中进行测试才能看到。

      【讨论】:

        【解决方案7】:

        在任何重要的数据库驱动应用程序中,您都无法避免连接。

        联接...本身并不是问题的根本原因,但性能不佳可能是由于查询编写不佳或数据库设计不佳等任何原因造成的。

        是的...在某些情况下,封装在存储函数中的连接可以通过使用准备好的字段来避免。也就是说,如果您确定需要某个连接的结果值以供重复使用..您不妨计算一次并将其存储以供重复使用。

        相关子查询是另一种选择。

        一般来说,如果您希望提高自己的技能,您应该问的问题是:如何编写高效的查询?

        【讨论】:

          猜你喜欢
          • 2021-09-03
          • 2021-12-19
          • 2022-11-01
          • 2022-01-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-09-06
          相关资源
          最近更新 更多