我正在评估各种选项,以针对Oracle中的单个临时数据集运行一堆高性能查询.在T-sql中,我可能会使用内存中的临时表,但Oracle没有与此功能完全等效的内容.
我目前看到这些选项:
1.全球临时表
CREATE GLOBAL TEMPORARY TABLE test_temp_t (
n NUMBER(10),s VARCHAR2(10)
) ON COMMIT DELETE ROWS; -- Other configurations are possible,too
DECLARE
t test_t;
n NUMBER(10);
BEGIN
-- Replace this with the actual temporary data set generation
INSERT INTO test_temp_t
SELECT MOD(level,10),'' || MOD(level,12)
FROM dual
CONNECT BY level < 1000000;
-- Replace this example query with more interesting statistics
SELECT COUNT(DISTINCT t.n)
INTO n
FROM test_temp_t t;
DBMS_OUTPUT.PUT_LINE(n);
END;
计划:
----------------------------------------------------
| Id | Operation | A-Rows | A-Time |
----------------------------------------------------
| 0 | SELECT STATEMENT | 1 |00:00:00.27 |
| 1 | SORT AGGREGATE | 1 |00:00:00.27 |
| 2 | VIEW | 10 |00:00:00.27 |
| 3 | HASH GROUP BY | 10 |00:00:00.27 |
| 4 | TABLE ACCESS FULL| 999K|00:00:00.11 |
----------------------------------------------------
2.解决PL / sql表类型变量的问题
CREATE TYPE test_o AS OBJECT (n NUMBER(10),s VARCHAR2(10));
CREATE TYPE test_t AS TABLE OF test_o;
DECLARE
t test_t;
n NUMBER(10);
BEGIN
-- Replace this with the actual temporary data set generation
SELECT test_o(MOD(level,12))
BULK COLLECT INTO t
FROM dual
CONNECT BY level < 1000000;
-- Replace this example query with more interesting statistics
SELECT COUNT(DISTINCT n)
INTO n
FROM TABLE(t) t;
DBMS_OUTPUT.PUT_LINE(n);
END;
计划:
------------------------------------------------------------------
| Id | Operation | A-Rows | A-Time |
------------------------------------------------------------------
| 0 | SELECT STATEMENT | 1 |00:00:00.68 |
| 1 | SORT GROUP BY | 1 |00:00:00.68 |
| 2 | COLLECTION ITERATOR PICKLER FETCH| 999K|00:00:00.22 |
------------------------------------------------------------------
3.物化观点
我正在为这个用例排除它们,因为所讨论的临时数据集相当复杂,对更新物化视图的影响太大了.
真实的数据考虑
以上是我正在尝试做的例子.真实的数据集涉及:
>临时数据从大约15个连接表中非规范化.
>它产生大约2-20x /秒.
>每个临时数据集的实际行数大约为10-200(不像上例中那么大).
>系统的每个用户都有自己的临时数据集(总共1M用户,10k并发用户).
>一旦建立了数据集,就应该针对它运行大约10-50个分析查询.
>这些分析必须在线运行,即不能将它们推迟到批处理作业.
问题
根据我的直觉,临时表查询“应该”较慢,因为它(可能)涉及I / O和磁盘访问,而PL / sql集合查询仅仅是内存中的解决方案.但是在我的琐碎基准测试中,情况并非如此,因为临时表查询比PLx sql集合查询要多3倍.为什么会这样?是否有一些PL / sql< - > sql上下文切换发生了什么?
我是否有其他选项可以在明确定义的临时数据集上进行快速(但广泛的)“内存中”数据分析?是否有任何重要的公开基准比较各种选项?