我想优化 sql 查询。它在内部执行 Hash Join,因此它会进行全表扫描以获取结果。
alter session set "_hash_join_enabled" = false;
如果我使用上面的命令,oracle 采用嵌套循环并且没有全表扫描。
任何人都可以建议我使用这个的实时应用程序吗?
我想优化 sql 查询。它在内部执行 Hash Join,因此它会进行全表扫描以获取结果。
alter session set "_hash_join_enabled" = false;
如果我使用上面的命令,oracle 采用嵌套循环并且没有全表扫描。
任何人都可以建议我使用这个的实时应用程序吗?
问题不在于全表扫描,而在于执行查询的时间。优化器选择散列连接和 FTS 是因为它认为它比嵌套循环更快。通常这是统计数据或查询编写方式的问题。
如果你真的想通过这样的提示来做到这一点,那么在语句级别使用它,就像评论说的那样(例如 opt_param('_hash_join_enabled','false'),或 use_nl(把表名放在这里你想要的顺序))。
通常,任何以下划线开头的参数都是未记录的参数。在生产系统中设置任何未记录的参数是不明智的,除非 Oracle 支持明确告诉您这样做。这几乎总是在他们确认您遇到特定错误并帮助您确定最好的解决方法是设置一个未记录的参数之后发生。
禁用会话的哈希连接意味着该会话运行的任何操作都不会考虑使用哈希连接。至少,在您设置类似的内容之前,您需要分析该会话可能运行的每个查询的计划(很可能是您的应用程序可能运行的每个查询),以确定它们当前是否正在使用哈希连接以及什么如果他们使用其他联接,则预期的性能影响将是。而且您希望在较低的环境中进行完整的性能回归测试,以确定更改对应用程序性能的影响。系统很少有一些从使用哈希连接中受益的查询。
如果问题是单个查询,那么在会话级别进行任何参数更改都可能是矫枉过正。在单个查询级别解决单个查询的问题更有意义。大多数情况下,当 Oracle 优化器选择一个错误的计划时,问题是您对一个或多个对象的统计信息不正确。这导致 Oracle 相信表扫描将比实际效率更高,或者预期嵌套循环连接的效率将低于实际效率。可能是统计数据已过时或缺少特定统计数据(即,具有倾斜数据的列上的直方图)。如果您可以通过修复统计信息来解决问题,那么这是首选方法。
如果您无法通过修复统计信息来解决问题,则可以考虑对查询应用提示。您可以在特定查询的提示中设置未记录的参数,但最好坚持使用已记录的提示。如果我试图改变计划,我想要告诉优化器你想要发生什么的提示,比如use_nl
提示,而不是告诉优化器什么是不允许的提示。如果禁用散列连接,Oracle 很可能会因为统计信息更改或数据库升级而开始执行合并连接而不是嵌套循环连接。