【发布时间】:2015-03-06 10:11:57
【问题描述】:
考虑以下查询:
SELECT *
FROM (
SELECT ARRM.*, ROWNUM
FROM CRS_ARRANGEMENTS ARRM
WHERE
CONCAT(ARRM.NBR_ARRANGEMENT, ARRM.TYP_PRODUCT_ARRANGEMENT) >
CONCAT('0000000000000000', '0000')
ORDER BY
ARRM.NBR_ARRANGEMENT,
ARRM.TYP_PRODUCT_ARRANGEMENT,
ARRM.COD_CURRENCY)
WHERE ROWNUM < 1000;
此查询在具有 10 000 000 个条目的表上运行。从 Oracle SQL Developer 或我的应用程序运行查询时需要 4 分钟才能运行!不幸的是,这也是我正在编写的应用程序内部的行为。将值从 1000 更改为 10 完全没有影响,这表明它正在执行全表扫描。
但是,当从 SQuirreL 运行时,查询会在 几毫秒内返回。这怎么可能?解释在 SQuirreL 中生成的计划给出:
但是对于同一个查询,Oracle SQL Developer 会生成不同的解释计划:
知道这种行为差异是如何产生的吗?我无法理解它。我尝试使用 JPA 和原始 JDBC。在应用程序中,我需要解析所有 10 000 000 条记录,并且此查询用于分页,因此不能选择等待 4 分钟(这需要 27 天)。
注意:我在 SQuirreL 和我的应用程序中使用相同的 Oracle jdbc 驱动程序,因此这不是问题的根源。
【问题讨论】:
-
执行 SELECT COUNT(*) .... 看看性能差距是否仍然存在。我猜 SQuirrel 没有得到所有的数据。
-
SQuirreL 确实获得了所有数据,这没有区别。当数据库表中仅加载 100 000 个条目时,没有这种差异。
-
你看过这个帖子吗:community.oracle.com/thread/945873 可能是绑定变量偷看的问题。
-
这不是绑定变量窥视,因为查询对相同的变量执行不同。