【发布时间】:2013-12-08 10:15:22
【问题描述】:
在支持 MS SQL Server、MySQL 和 Oracle 的应用中,有一个包含以下相关列的表(此处显示的类型适用于 Oracle):
ShortText VARCHAR2(1700) indexed
LongText CLOB
应用程序在 ShortText 中存储 850 个字符或更少的值,在 LongText 中存储更长的值。我需要创建一个返回该数据的视图,无论它位于哪个列。这适用于 SQL Server 和 MySQL:
SELECT
CASE
WHEN ShortText IS NOT NULL THEN ShortText
ELSE LongText
END AS TheValue
FROM MyTable
但是,在 Oracle 上,它会生成此错误:
ORA-00932: inconsistent datatypes: expected CHAR got CLOB
...意味着Oracle不会将两列隐式转换为相同的类型,因此查询必须显式执行。不希望数据被截断,因此所使用的类型必须能够容纳与 CLOB 一样多的数据,据我了解(不是 Oracle 专家)意味着 CLOB,只有,没有其他选择可用。
这适用于 Oracle:
SELECT
CASE
WHEN ShortText IS NOT NULL THEN TO_CLOB(ShortText)
ELSE LongText
END AS TheValue
FROM MyTable
但是,性能非常糟糕。直接返回 LongText 的查询大约 9k 行需要 70-80 毫秒,但上述构造需要 30 到 60 秒,不可接受。
所以:
- 是否有任何其他 Oracle 类型我可以强制这两列 可以容纳与 CLOB 一样多的数据?理想情况下还有更多 面向文本的,例如 MySQL 的 LONGTEXT,或 SQL Server 的 NTEXT(甚至 更好,NVARCHAR(MAX))?
- 我应该考虑其他任何方法吗?
一些细节,尤其是@Guido Leenders 要求的细节:
Oracle版本:Oracle Database 11g 11.2.0.1.0 64bit Production 不确定我是否是唯一的用户,但相对时间仍然惊人。 我看到我之前发布的性能的小桌子的统计数据: 行数:9,237 varchar 列总长度:148,516 clob 列总长度:227,020
【问题讨论】:
-
如果你要将所有的短文本放入长文本中,并且只有一个 CLOB 列,这是否会使事情变得更快?
-
更容易,但是如上所述,短的被索引了,我很漂亮 CLOB 不能。它也可以连接,并支持 WHERE 子句中的等于测试。这是一些通用存储基础架构的一部分,其中数据的子集用于特定目的,因此当已知相关的特定数据始终适合短列时,这些功能很有价值。
-
请注意,Oracle 12c 将 varchar2 的最大大小增加到 32,767。
-
@David Aldridge:很高兴知道,将来会有所帮助,但目前,该应用还需要支持旧的 Oracle 版本。
标签: performance oracle casting clob coerce