【发布时间】:2011-11-23 12:36:17
【问题描述】:
我在 Oracle (11.2.0.1.0) 上遇到一个问题,左外连接过多(或者连接表中的列过多)会导致以下错误:
ORA-03113: end-of-file on communication channel
alert.log 文件将潜在错误显示为:
ORA-07445: exception encountered: core dump...
我们之前也看到过类似的问题,但出现了不同的错误:
ORA-01445: cannot select ROWID from, or sample, a join view without a
key-preserved table
When ANSI SQL Join Syntax Does Not Work in Oracle
测试用例:
-- create 100 colum table
CREATE TABLE BIG_TABLE
(
c1 NVARCHAR2(1), c2 NVARCHAR2(1), c3 NVARCHAR2(1), c4 NVARCHAR2(1), c5 NVARCHAR2(1), c6 NVARCHAR2(1), c7 NVARCHAR2(1), c8 NVARCHAR2(1), c9 NVARCHAR2(1), c10 NVARCHAR2(1),
c11 NVARCHAR2(1), c12 NVARCHAR2(1), c13 NVARCHAR2(1), c14 NVARCHAR2(1), c15 NVARCHAR2(1), c16 NVARCHAR2(1), c17 NVARCHAR2(1), c18 NVARCHAR2(1), c19 NVARCHAR2(1), c20 NVARCHAR2(1),
c21 NVARCHAR2(1), c22 NVARCHAR2(1), c23 NVARCHAR2(1), c24 NVARCHAR2(1), c25 NVARCHAR2(1), c26 NVARCHAR2(1), c27 NVARCHAR2(1), c28 NVARCHAR2(1), c29 NVARCHAR2(1), c30 NVARCHAR2(1),
c31 NVARCHAR2(1), c32 NVARCHAR2(1), c33 NVARCHAR2(1), c34 NVARCHAR2(1), c35 NVARCHAR2(1), c36 NVARCHAR2(1), c37 NVARCHAR2(1), c38 NVARCHAR2(1), c39 NVARCHAR2(1), c40 NVARCHAR2(1),
c41 NVARCHAR2(1), c42 NVARCHAR2(1), c43 NVARCHAR2(1), c44 NVARCHAR2(1), c45 NVARCHAR2(1), c46 NVARCHAR2(1), c47 NVARCHAR2(1), c48 NVARCHAR2(1), c49 NVARCHAR2(1), c50 NVARCHAR2(1),
c51 NVARCHAR2(1), c52 NVARCHAR2(1), c53 NVARCHAR2(1), c54 NVARCHAR2(1), c55 NVARCHAR2(1), c56 NVARCHAR2(1), c57 NVARCHAR2(1), c58 NVARCHAR2(1), c59 NVARCHAR2(1), c60 NVARCHAR2(1),
c61 NVARCHAR2(1), c62 NVARCHAR2(1), c63 NVARCHAR2(1), c64 NVARCHAR2(1), c65 NVARCHAR2(1), c66 NVARCHAR2(1), c67 NVARCHAR2(1), c68 NVARCHAR2(1), c69 NVARCHAR2(1), c70 NVARCHAR2(1),
c71 NVARCHAR2(1), c72 NVARCHAR2(1), c73 NVARCHAR2(1), c74 NVARCHAR2(1), c75 NVARCHAR2(1), c76 NVARCHAR2(1), c77 NVARCHAR2(1), c78 NVARCHAR2(1), c79 NVARCHAR2(1), c80 NVARCHAR2(1),
c81 NVARCHAR2(1), c82 NVARCHAR2(1), c83 NVARCHAR2(1), c84 NVARCHAR2(1), c85 NVARCHAR2(1), c86 NVARCHAR2(1), c87 NVARCHAR2(1), c88 NVARCHAR2(1), c89 NVARCHAR2(1), c90 NVARCHAR2(1),
c91 NVARCHAR2(1), c92 NVARCHAR2(1), c93 NVARCHAR2(1), c94 NVARCHAR2(1), c95 NVARCHAR2(1), c96 NVARCHAR2(1), c97 NVARCHAR2(1), c98 NVARCHAR2(1), c99 NVARCHAR2(1), c100 NVARCHAR2(1)
)
/
-- left outer join query (10 joins = 1000 columns)
SELECT
*
FROM
BIG_TABLE
LEFT OUTER JOIN BIG_TABLE BT1 ON 1 = 1
LEFT OUTER JOIN BIG_TABLE BT2 ON 1 = 1
LEFT OUTER JOIN BIG_TABLE BT3 ON 1 = 1
LEFT OUTER JOIN BIG_TABLE BT4 ON 1 = 1
LEFT OUTER JOIN BIG_TABLE BT5 ON 1 = 1
LEFT OUTER JOIN BIG_TABLE BT6 ON 1 = 1
LEFT OUTER JOIN BIG_TABLE BT7 ON 1 = 1
LEFT OUTER JOIN BIG_TABLE BT8 ON 1 = 1
LEFT OUTER JOIN BIG_TABLE BT9 ON 1 = 1
LEFT OUTER JOIN BIG_TABLE BT10 ON 1 = 1
--LEFT OUTER JOIN BIG_TABLE BT11 ON 1 = 1
如果你取消最后一行的注释,将会导致错误。
--
我已经针对以下版本进行了测试:
10.2.0.1.0 = ORA-01445:无法从没有保留键的表的连接视图中选择 ROWID。
(请注意,您需要注释掉最后两个连接才能使这项工作正常进行 - 除了连接的表之外,它似乎还包括第一个表的列)
11.1.0.6.0 = 好的
11.2.0.1.0 = ORA-03113:通信通道上的文件结束
有人可以确认我的结果(尤其是最后一个结果),如果可能的话,建议任何解决方法?
谢谢, 本
【问题讨论】:
-
不带连接条件的连接 (
ON 1 = 1) 不是外连接,它是一种混淆的方式来编写cross join -
对于 Oracle 10 或更低版本的查询包含太多列而无法处理需求的情况,似乎也需要重构数据库。是的,这句话太可怕了。