Seb*_*ino 8 sql oracle performance select
我是oracle的新手,我不得不反对这个问题.
我有一张桌子,里面有大约520万行.我必须获取所有行并在NoSQL数据库中导入它们(非规范化).
该表有两个整数字段C_ID和A_ID以及3个索引,一个在C_ID上,一个在A_ID上,一个在两个字段上.
我一开始就尝试过这种方式:
SELECT C_ID, A_ID FROM M_TABLE;
Run Code Online (Sandbox Code Playgroud)
这从来没有给我任何合理时间的结果(我没有可能测量时间,因为它似乎永远不会完成).
我用这种方式更改了查询:
SELECT /*+ ALL_ROWS */ C_ID, A_ID FROM (SELECT
rownum rn, C_ID, A_ID
FROM
M_TABLE WHERE rownum < ((:1 * :2 ) +1 )) WHERE rn >= (((:1 -1) * :2 ) +1 );
Run Code Online (Sandbox Code Playgroud)
我使用3个线程并行运行此查询,并使用大小为1000的页面进行分页.
我试着介绍三种优化:
1)我在表格上创建了统计数据:
ANALYZE TABLE TABLE_M ESTIMATE STATISTICS SAMPLE 5 PERCENT;
Run Code Online (Sandbox Code Playgroud)
2)我在8个分区中对表进行了分区.
3)我用并行选项创建了表.
现在我能够每秒获取10000行,因此整个过程大约需要15个小时才能完成(数据库运行在4核,8 GB机器上).
问题是我需要在最多5个小时内完成所有操作.
我没有想法,因此,在我要求新机器之前,你知道如何在这种情况下提高性能.
小智 5
Oracle非常聪明地告诉我们它花了多少时间.您可以通过使用Oracle的扩展SQL跟踪(换言之,10046跟踪)跟踪会话来执行此操作.您的查询是从一个包含大量数据的表中提取数据.检查您的IO速率(db_file_scattered_read),这可能是查询的最常见等待事件之一.
希望能帮助到你.
你怎么处理你的结果?是直接使用PL/SQL获取文件还是使用其他应用程序处理数据?它是通过网络发送的吗?(这可能是低悬的果实).
我问的原因是通常FULL SCAN(没有ORDER BY)会立即返回第一行.如果您要将结果输出到文件,您应该会看到它立即开始填满.如果不这样做,这意味着在段的开头有很多空的空间,这可以解释为什么查询永远不会返回(至少在合理的时间内).
所以当你说你的查询没有返回时我有点担心,你怎么能说出来?以下块是否返回?
DECLARE
l NUMBER := 0;
BEGIN
FOR cc IN (SELECT C_ID, A_ID FROM M_TABLE) LOOP
l := l + 1;
EXIT WHEN l >= 100000;
END LOOP;
END;
Run Code Online (Sandbox Code Playgroud)
如果是,则表示正在处理您的全扫描.通过对上述查询进行计时,您应该能够计算完整单个SCAN所需的时间,假设该段是均匀密集的.
读取500M行是很多工作但行很小,所以如果表段压缩得很好,Oracle应该在合理的时间内返回所有行.如果重复删除然后加载INSERT /*+APPEND*/例如,表段可能具有低效的空间配置.重建table(ALTER TABLE MOVE)将删除段中所有空的无用空间.顺便说一句,当您对表进行分区时,您确实重建了它,因此这可能就是您的查询现在返回的原因!
在任何情况下,我都会建议您重建FULL TABLE SCAN,可能是在重建了表以重置任何空白区域和高水位标记之后.单个FULL TABLE SCAN是迄今为止访问大量数据的最可靠方法(也是最有效的方法之一).
如果您需要进一步提高性能,我建议您看看ROWID分区(DIY并行处理方案)或内置包DBMS_PARALLEL_EXECUTE.
| 归档时间: |
|
| 查看次数: |
5725 次 |
| 最近记录: |