我最近编写了一个复杂的 SELECT 语句(基于许多非常非常复杂的视图),如果从我的桌面上的 Toad 运行,则需要 1 小时 50 分钟才能执行,而如果从使用 cx_Oracle 库的 Python 脚本运行(写入每 50 行刷新到磁盘),则只快几分钟。单个结果集的总大小约为 8000 行,总计 5MB。在执行过程中,我的工作站没有出现抖动,CPU 负载也相当低。
在服务器上运行完全相同的查询竟然花了 21 秒才生成完全相同的结果集。这也是由相同的 Python/cx_Oracle 脚本生成的。
将 5MB 的结果集文件从服务器传输到我的工作站仅用了 3 秒,因此我认为网络带宽不是直接问题。
SQL*Net 或其相关库可能是罪魁祸首吗?当通过网络调用查询时,是否存在一些非线性内存管理问题?5MB 的结果集很大,但在当今时代并不算巨大。是否有一些缓冲区大小配置设置会有所帮助?我正在使用原始 Oracle 客户端安装。
工作站是 Windows XP Pro SP3(仅 1GB RAM),带有 Oracle 10g 客户端和 Toad for Oracle Xpert 9.7.2.5 以及带有 cx_Oracle 5.0.2 的 Python 2.6.2。服务器是四核 Xeon 3.8GHz 8GB 服务器上的 Red Hat 2.6.9-67.ELsmp,运行 Oracle 10.2.0.4、Python 2.3.4、cx_Oracle 4.4.1。
编辑:哎呀!该文件只是5兆字节,不是 GB。非常抱歉。
已解决:在我提到的提取查询之前运行了一个填充脚本。重新运行该填充脚本后,无论客户端程序位于何处,提取查询都需要 2 小时才能运行。在第一次长时间运行之后,结果集一定被缓存在某个地方,直到我系统地检查了所有组合后,我才注意到这种影响。
答案1
需要考虑的两点:
您是否先在 Toad 中执行查询,然后在 python+cx_Oracle 中执行查询?第一次执行查询时,Oracle 需要解析查询、创建执行计划并执行计划:从磁盘读入内存(缓冲区缓存)、执行连接等……第二次,Oracle 使用相同的执行计划(存储在 SGA 中),并从缓冲区缓存而不是磁盘读取。第二次执行相同查询时,时间会少很多。
将 8000 行/5GB 数据(每行 655Kbytes!!!)加载到 TOAD 中,然后在 GUI 中显示它们,可能需要花费大量时间。使用 python+cx_Oracle 时不会显示任何内容,因此您可以节省大量时间。
已编辑:好的,因此 8000 行/5 Mb 数据(每行 655 字节)对于 TOAD 显示来说应该没有问题。
- 将 Linux 中的 Oracle 环境变量与 Windows 中的 HKEY_LOCAL_MACHINE\Software\Oracle 注册表变量进行比较。检查 NLS_SORT、NLS_LANG、NLS_... 变量是否具有相同的值。
答案2
跟踪 oracle 中的执行情况,您可能会看到您的工作站正在获取小块数据并快速增加延迟。
解决方案可能是批量获取结果,就像这里所做的那样:
解决 TOAD 中的 Oracle Contention;查看 toadworld,搜索
http://www.toadworld.com/Experts/GuyHarrisonsImprovingOraclePerformance/ResolvingOracleContention/May2008OracleNetworkContention/tabid/374/Default.aspx
(抱歉,无法添加超链接)
答案3
我不太了解 Oracle,但之前使用其他数据库的网络协议的经验告诉我,它们完全忽略了延迟问题。换句话说,即使没有太大的延迟,数量传输的数据,如果必须为每个值多次往返服务器,事情仍然会变得缓慢。
如果您在网络中添加一点延迟,您可以测试这个理论(我知道这在 Linux 中是可能的,我只能想象在 Windows 中有某种方法可以做到这一点)并看看它是否会显著影响整体运行时间。
另一种可能性是,部分处理可能在客户端完成,可能需要传输远超 5 GB 的中间数据才能获得结果。不过,这可能会在您的桌面上显示为相当明显的负载量,因此这种情况不太可能发生。
答案4
应将一个 SELECT 语句完整地发送到服务器进行解析和执行。由客户端来管理如何返回这些结果。我敢打赌,问题在于您的客户端如何获取结果。我已经有一段时间没用过 TOAD 了,所以我不知道它是否在批量提取数据,但正如 @slovon 所说,这是可以大大提高速度的地方。
只是为了好玩,看看从您的工作站到服务器的 traceroute 报告了什么,反之亦然。
编辑:另一个要尝试的方法是在服务器上运行 python 脚本,但通过服务器上的侦听器进行 TNS 连接。这应该可以让您了解 TNS 软件在消除任何中间网络问题的同时对您的查询产生了什么影响。
另外,请确保您的 DNS 运行正常(必须能够进行反向查找),并且您没有在服务器上使用 DHCP。主机名中也不允许使用下划线。