oracle优化问题 我写了一个存储过程,使用游标对数据进行插入操作,涉及到很多表,其中一些是主从表关系,按顺序下来,主表生成数据,再生成子表的。 最近碰到一个问题,由于有的数据量过大,造成速度很慢,在10几万条以上。想请教下高手,有没有好的方法进行优化,提高下速度! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 只要没有太多大块头大对象,10几万对ORACLE来说真不多。贴出SQL。 你关心下表与表之间的关联方式~要让SQL尽量最优,如果速度还不行,你就要考试数据库结构了· 呵呵,问题太泛泛了给你些意见吧,多看看批量插入 insert into a select * from b;在有就是注意表与表之间的关联了。你可以吧具体的表结构和需求拿出来,我们大家给你分析一下啊 FOR rbl_survey_bound in cbl_survey_bound(aFlowSN(i)) loop --获取旧勘测ID oldSB_ID := rbl_survey_bound.SB_ID; --获取新的勘测ID select S_bl_survey_bound.NEXTVAL || SeqBaseCode into newSB_ID from dual; --勘测定界表,SB_ID用序列取值,其他字段用原来的值 insert into BL_SURVEY_BOUND (SB_ID, PL_ID, PB_PB_ID, BPL_BPL_ID, UNIT_NAME, HDL_ENO, ADDRESS, COM_TEL, CHARGE_UNIT, PROPERTY, LOCATION, USAGE, APPL_DATE, RELT_FILE, CHARGE_ENO, CHECK_ENO, PRINCIPAL, MAP_NO, COORD_SYSTEM, PNT_COUNT, PNT_DATE, NOTE, SB_NAME, RANGE_MAP_LINK, BPL_LINK, BC_BC_ID, REMARK, FLOWSN) select newSB_ID, PL_ID, PB_PB_ID, BPL_BPL_ID, UNIT_NAME, HDL_ENO, ADDRESS, COM_TEL, CHARGE_UNIT, PROPERTY, LOCATION, USAGE, APPL_DATE, RELT_FILE, CHARGE_ENO, CHECK_ENO, PRINCIPAL, MAP_NO, COORD_SYSTEM, PNT_COUNT, PNT_DATE, NOTE, SB_NAME, RANGE_MAP_LINK, BPL_LINK, BC_BC_ID, REMARK, NewFlowSN from BL_SURVEY_BOUND where SB_ID = oldSB_ID; --从旧勘测获取记录插入新勘测记录 --勘测定界技术报告书表,DTR_ID用序列取值,SB_SB_ID用新的勘测ID,其他字段用原来的值 insert into BL_DELIMITATION_TAC_RPT (DTR_ID, PL_ID, SB_SB_ID, PB_PB_ID, DTR_NO, UNIT, PROJ_NAME, DWFZR, ZLFSR, ZLSHR, XMFZR, RIQI) select s_BL_DELIMITATION_TAC_RPT.Nextval || SeqBaseCode, PL_ID, newSB_ID, PB_PB_ID, DTR_NO, UNIT, PROJ_NAME, DWFZR, ZLFSR, ZLSHR, XMFZR, RIQI from BL_DELIMITATION_TAC_RPT where SB_SB_ID = oldSB_ID; --从旧勘测获取记录插入新勘测记录 --勘测定界技术说明表,PCD_ID用序列取值,SB_SB_ID用新的勘测ID,其他字段用原来的值 insert into BL_DelimitationTac (DT_ID, PL_ID, SB_SB_ID, PB_PB_ID, BPL_BPL_ID, DELIMITATIONTAC_TITLE, HEDING, YOU, KANCERIQI, MIANJIWEI, MU, JIEZHIZHUANG, FANGFASHI, FUZEREN, RIQI, COMPUTATION_UNIT, PRECISION, PROJECTION_TYPE, HOW_MANY_ANGLE, TERRAIN_NO, X_MOVE, Y_MOVE, Z_MOVE, X_ROTATE, Y_ROTATE, Z_ROTATE, MEASURE, FORMAT_VER, MAKE_UNIT, MAKE_DATE, COORD_SYS) select s_BL_DelimitationTac.Nextval || SeqBaseCode, PL_ID, newSB_ID, PB_PB_ID, BPL_BPL_ID, DELIMITATIONTAC_TITLE, HEDING, YOU, KANCERIQI, MIANJIWEI, MU, JIEZHIZHUANG, FANGFASHI, FUZEREN, RIQI, COMPUTATION_UNIT, PRECISION, PROJECTION_TYPE, HOW_MANY_ANGLE, TERRAIN_NO, X_MOVE, Y_MOVE, Z_MOVE, X_ROTATE, Y_ROTATE, Z_ROTATE, MEASURE, FORMAT_VER, MAKE_UNIT, MAKE_DATE, COORD_SYS from BL_DelimitationTac where SB_SB_ID = oldSB_ID; --从旧勘测获取记录插入新勘测记录 FOR rBL_CLASS_AREA IN cBL_CLASS_AREA(oldSB_ID) LOOP --获取新的CA_ID select S_BL_CLASS_AREA.NEXTVAL || SeqBaseCode into newCA_ID from dual; --插入土地分类面积表主表新记录,其中CA_ID用新的CA_ID,SB_SB_ID用新的勘测ID,其他字段用原来的值 insert into BL_CLASS_AREA (CA_ID, PL_ID, SB_SB_ID, PB_PB_ID, County, COUNTRYSIDE, VISIBLE_SETING) values (newCA_ID, rBL_CLASS_AREA.PL_ID, newSB_ID, rBL_CLASS_AREA.PB_PB_ID, rBL_CLASS_AREA.County, rBL_CLASS_AREA.COUNTRYSIDE, rBL_CLASS_AREA.VISIBLE_SETING); FOR rDTL IN cBL_CLASS_AREA_DTL(rBL_CLASS_AREA.CA_ID) LOOP --土地分类面积表子表,CAD_ID用序列取值,CA_ID用新的CA_ID,其他字段用原来的值 select S_BL_CLASS_AREA_DTL.NEXTVAL || SeqBaseCode into newCAD_ID from dual; insert into BL_CLASS_AREA_DTL (cad_id, ca_id, unit_name, theowner, ldlrs, rjgd, yyrks, rjgdzh, get_type ) values (newCAD_ID, newCA_ID, rDTL.unit_name, rDTL.theowner, rdtl.rjgdzh, rDTL.ldlrs, rDTL.rjgd, rDTL.yyrks, rdtl.get_type ); insert into SourceVSBatch (SourceFlowsn, NewFlowsn, Tablename, Keyfields, Sourcekeyvalues, Newkeyvalues) values (aFlowSN(i), NewFlowSN, 'BL_CLASS_AREA_DTL', 'CAD_ID', rDTL.CAD_ID, newCAD_ID); --插入土地分类面积表子表拆分表 FOR rDTL2 IN cBL_CLASS_AREA_DTL2(RDTL.CAD_ID) LOOP SELECT S_BL_CLASS_AREA_DTL2.NEXTVAL || SeqBaseCode into newcadd_ID from dual; insert into bl_class_area_dtl2 ( cadd_id, cad_id, dl_id, dl_value, dl_value_hj ) values ( newcadd_ID, newCAD_ID, rDTL2.Dl_Id, rDTL2.Dl_Value, rdtl2.dl_value_hj ); insert into SourceVSBatch (SourceFlowsn, NewFlowsn, Tablename, Keyfields, Sourcekeyvalues, Newkeyvalues) values (aFlowSN(i), NewFlowSN, 'BL_CLASS_AREA_DTL2', 'CADD_ID', rDTL2.CADD_ID, newcadd_ID); END LOOP; END LOOP; END LOOP; --end of cBL_CLASS_AREA cursor --从批次清单(勘测定界地块)游标逐地块处理 FOR rBL_PLOT IN cBL_PLOT(oldSB_ID) LOOP --获取旧地块ID oldPL_ID := rBL_PLOT.PL_ID; --获取新的地块ID select S_BL_PLOT.NEXTVAL || SeqBaseCode into newPL_ID from dual; --插入批次清单(勘测定界地块)新记录,其中PL_ID序列取值,SB_SB_ID用新的勘测ID,FLOWSN用新的业务序号, --Source_Flowsn用当前业务序号,其他字段用原来的值 insert into BL_PLOT (PL_ID, FLOWSN, SB_SB_ID, PB_PB_ID, PL_NO, PL_NAME, MAP_NO, PNT_COUNT, SURVEY_MAP_LINK, SHAPE_TYPE, PURPOSE, LAND_TYPE, PNT_SURVEY, PNT_CHECKER, DIKUAI_NO, DIKUAI_AREA, LAND_AREA, AUTO_AREA, FOR_PLACE, REGIONCODE) values (newPL_ID, NewFlowSN, --oldSB_ID,--20090316 newSB_ID, rBL_PLOT.PB_PB_ID, rBL_PLOT.PL_NO, rBL_PLOT.PL_NAME, rBL_PLOT.MAP_NO, rBL_PLOT.PNT_COUNT, rBL_PLOT.SURVEY_MAP_LINK, rBL_PLOT.SHAPE_TYPE, rBL_PLOT.PURPOSE, rBL_PLOT.LAND_TYPE, rBL_PLOT.PNT_SURVEY, rBL_PLOT.PNT_CHECKER, rBL_PLOT.DIKUAI_NO, rBL_PLOT.DIKUAI_AREA, rBL_PLOT.LAND_AREA, rBL_PLOT.AUTO_AREA, rBL_PLOT.FOR_PLACE, rBL_PLOT.REGIONCODE); --插入地块项目对应表 insert into bl_proj_plot (flowsn, pj_id, pl_id) values (NewFlowSN, newPJ_ID, newPL_ID); --流程合并表记录对照表 insert into SourceVSBatch (SourceFlowsn, NewFlowsn, Tablename, Keyfields, Sourcekeyvalues, Newkeyvalues) values (aFlowSN(i), NewFlowSN, 'BL_PLOT', 'PL_ID', rBL_PLOT.PL_ID, newPL_ID); FOR rBl_PLOT_USE IN cBl_PLOT_USE(oldPL_ID) LOOP --插入地块用途面积 select S_Bl_PLOT_USE.NEXTVAL || SeqBaseCode into newUSE_ID from dual; insert into Bl_PLOT_USE (USE_ID, FLOWSN, PL_ID, USENAME, USEAREA) values (newUSE_ID, NewFlowSN, newPL_ID, rBl_PLOT_USE.USENAME, rBl_PLOT_USE.USEAREA); END LOOP; --从土地分类面积表主表游标获取该旧地块的分类面积主表记录,并逐记录处理 --界址点成果表,PCD_ID用序列取值,PL_ID用新的地块ID,SB_SB_ID用新的勘测ID,其他字段用原来的值 insert into BL_PNT_COORD (PCD_ID, PL_ID, SB_SB_ID, PB_PB_ID, PNT_NO, X_COORD, Y_COORD, BORDER_LENGTH, MATERIAL, REMARK, COORD_FALG, SHAPE_GROUP, PNT_SERIAL) select s_BL_PNT_COORD.Nextval || SeqBaseCode, newPL_ID, newSB_ID, PB_PB_ID, PNT_NO, X_COORD, Y_COORD, BORDER_LENGTH, MATERIAL, REMARK, COORD_FALG, SHAPE_GROUP, PNT_SERIAL from BL_PNT_COORD where PL_ID = oldPL_ID; --从旧地块获取记录插入新地块记录 end loop;end loop; 一点建议1. 针对你贴出的代码,假设数据源就是数组cBL_CLASS_AREA_DTL,可以用for all关键字,避免使用循环,至少提高10倍以上效率。具体用法google一下吧,不难的2. 重新考虑数据源在哪里,如果数组cBL_CLASS_AREA_DTL本身就是从别的表来的,可以不用数组,直接insert ...select ...3. 重新考虑数据源在哪里,如果csv文件等,可以用SQL*Loader,10万数据,在笔记本上顶多10几秒就导入4. 如果insert 是必须的,简单的/* append */可以提高不少效率,no logging也能提高一倍左右效率,最理想是create table ... as select5. 哥们还得多看书,基础的东西欠缺的比较多 为什么sys用户的很多系统权限对应的ADMIN_OPTION为no还能给其他用户授权 菜鸟问题,我想用oracleconnection连接数据库都应该有哪些配置环境或者命名空间。 急!oracle10g可以按表空间导出导入吗(同一个数据库在两个表空间之间导数据)? 时间格式的查询 如何判断A表是B表的子表 oracle序列问题 是否一定需要再建一个用户,在改用户下建实例? 请问oracle中的除法运算为什么除错? 参与者有分!!!!!!!!!!! sql*plus中怎样把存储过程中打印的结果显示出来? ORACLE查询树的分支裁剪问题 oracle 9i 安装在2003上的小问题
贴出SQL。
oldSB_ID := rbl_survey_bound.SB_ID; --获取新的勘测ID
select S_bl_survey_bound.NEXTVAL || SeqBaseCode into newSB_ID from dual; --勘测定界表,SB_ID用序列取值,其他字段用原来的值
insert into BL_SURVEY_BOUND
(SB_ID,
PL_ID,
PB_PB_ID,
BPL_BPL_ID,
UNIT_NAME,
HDL_ENO,
ADDRESS,
COM_TEL,
CHARGE_UNIT,
PROPERTY,
LOCATION,
USAGE,
APPL_DATE,
RELT_FILE,
CHARGE_ENO,
CHECK_ENO,
PRINCIPAL,
MAP_NO,
COORD_SYSTEM,
PNT_COUNT,
PNT_DATE,
NOTE,
SB_NAME,
RANGE_MAP_LINK,
BPL_LINK,
BC_BC_ID,
REMARK,
FLOWSN)
select newSB_ID,
PL_ID,
PB_PB_ID,
BPL_BPL_ID,
UNIT_NAME,
HDL_ENO,
ADDRESS,
COM_TEL,
CHARGE_UNIT,
PROPERTY,
LOCATION,
USAGE,
APPL_DATE,
RELT_FILE,
CHARGE_ENO,
CHECK_ENO,
PRINCIPAL,
MAP_NO,
COORD_SYSTEM,
PNT_COUNT,
PNT_DATE,
NOTE,
SB_NAME,
RANGE_MAP_LINK,
BPL_LINK,
BC_BC_ID,
REMARK,
NewFlowSN
from BL_SURVEY_BOUND
where SB_ID = oldSB_ID; --从旧勘测获取记录插入新勘测记录
--勘测定界技术报告书表,DTR_ID用序列取值,SB_SB_ID用新的勘测ID,其他字段用原来的值
insert into BL_DELIMITATION_TAC_RPT
(DTR_ID,
PL_ID,
SB_SB_ID,
PB_PB_ID,
DTR_NO,
UNIT,
PROJ_NAME,
DWFZR,
ZLFSR,
ZLSHR,
XMFZR,
RIQI)
select s_BL_DELIMITATION_TAC_RPT.Nextval || SeqBaseCode,
PL_ID,
newSB_ID,
PB_PB_ID,
DTR_NO,
UNIT,
PROJ_NAME,
DWFZR,
ZLFSR,
ZLSHR,
XMFZR,
RIQI
from BL_DELIMITATION_TAC_RPT
where SB_SB_ID = oldSB_ID; --从旧勘测获取记录插入新勘测记录 --勘测定界技术说明表,PCD_ID用序列取值,SB_SB_ID用新的勘测ID,其他字段用原来的值
insert into BL_DelimitationTac
(DT_ID,
PL_ID,
SB_SB_ID,
PB_PB_ID,
BPL_BPL_ID,
DELIMITATIONTAC_TITLE,
HEDING,
YOU,
KANCERIQI,
MIANJIWEI,
MU,
JIEZHIZHUANG,
FANGFASHI,
FUZEREN,
RIQI,
COMPUTATION_UNIT,
PRECISION,
PROJECTION_TYPE,
HOW_MANY_ANGLE,
TERRAIN_NO,
X_MOVE,
Y_MOVE,
Z_MOVE,
X_ROTATE,
Y_ROTATE,
Z_ROTATE,
MEASURE,
FORMAT_VER,
MAKE_UNIT,
MAKE_DATE,
COORD_SYS)
select s_BL_DelimitationTac.Nextval || SeqBaseCode,
PL_ID,
newSB_ID,
PB_PB_ID,
BPL_BPL_ID,
DELIMITATIONTAC_TITLE,
HEDING,
YOU,
KANCERIQI,
MIANJIWEI,
MU,
JIEZHIZHUANG,
FANGFASHI,
FUZEREN,
RIQI,
COMPUTATION_UNIT,
PRECISION,
PROJECTION_TYPE,
HOW_MANY_ANGLE,
TERRAIN_NO,
X_MOVE,
Y_MOVE,
Z_MOVE,
X_ROTATE,
Y_ROTATE,
Z_ROTATE,
MEASURE,
FORMAT_VER,
MAKE_UNIT,
MAKE_DATE,
COORD_SYS
from BL_DelimitationTac
where SB_SB_ID = oldSB_ID; --从旧勘测获取记录插入新勘测记录 FOR rBL_CLASS_AREA IN cBL_CLASS_AREA(oldSB_ID) LOOP
--获取新的CA_ID
select S_BL_CLASS_AREA.NEXTVAL || SeqBaseCode
into newCA_ID
from dual; --插入土地分类面积表主表新记录,其中CA_ID用新的CA_ID,SB_SB_ID用新的勘测ID,其他字段用原来的值
insert into BL_CLASS_AREA
(CA_ID,
PL_ID,
SB_SB_ID,
PB_PB_ID,
County,
COUNTRYSIDE,
VISIBLE_SETING)
values
(newCA_ID,
rBL_CLASS_AREA.PL_ID,
newSB_ID,
rBL_CLASS_AREA.PB_PB_ID,
rBL_CLASS_AREA.County,
rBL_CLASS_AREA.COUNTRYSIDE,
rBL_CLASS_AREA.VISIBLE_SETING);
--土地分类面积表子表,CAD_ID用序列取值,CA_ID用新的CA_ID,其他字段用原来的值
select S_BL_CLASS_AREA_DTL.NEXTVAL || SeqBaseCode
into newCAD_ID
from dual;
insert into BL_CLASS_AREA_DTL
(cad_id,
ca_id,
unit_name,
theowner,
ldlrs,
rjgd,
yyrks,
rjgdzh,
get_type
)
values
(newCAD_ID,
newCA_ID,
rDTL.unit_name,
rDTL.theowner,
rdtl.rjgdzh,
rDTL.ldlrs,
rDTL.rjgd,
rDTL.yyrks,
rdtl.get_type
);
insert into SourceVSBatch
(SourceFlowsn,
NewFlowsn,
Tablename,
Keyfields,
Sourcekeyvalues,
Newkeyvalues)
values
(aFlowSN(i),
NewFlowSN,
'BL_CLASS_AREA_DTL',
'CAD_ID',
rDTL.CAD_ID,
newCAD_ID); --插入土地分类面积表子表拆分表
FOR rDTL2 IN cBL_CLASS_AREA_DTL2(RDTL.CAD_ID) LOOP
SELECT S_BL_CLASS_AREA_DTL2.NEXTVAL || SeqBaseCode
into newcadd_ID from dual;
insert into bl_class_area_dtl2
(
cadd_id,
cad_id,
dl_id,
dl_value,
dl_value_hj
)
values
(
newcadd_ID,
newCAD_ID,
rDTL2.Dl_Id,
rDTL2.Dl_Value,
rdtl2.dl_value_hj
); insert into SourceVSBatch
(SourceFlowsn,
NewFlowsn,
Tablename,
Keyfields,
Sourcekeyvalues,
Newkeyvalues)
values
(aFlowSN(i),
NewFlowSN,
'BL_CLASS_AREA_DTL2',
'CADD_ID',
rDTL2.CADD_ID,
newcadd_ID);
END LOOP;
END LOOP; END LOOP; --end of cBL_CLASS_AREA cursor
--从批次清单(勘测定界地块)游标逐地块处理
FOR rBL_PLOT IN cBL_PLOT(oldSB_ID) LOOP --获取旧地块ID
oldPL_ID := rBL_PLOT.PL_ID; --获取新的地块ID
select S_BL_PLOT.NEXTVAL || SeqBaseCode into newPL_ID from dual; --插入批次清单(勘测定界地块)新记录,其中PL_ID序列取值,SB_SB_ID用新的勘测ID,FLOWSN用新的业务序号,
--Source_Flowsn用当前业务序号,其他字段用原来的值
insert into BL_PLOT
(PL_ID,
FLOWSN,
SB_SB_ID,
PB_PB_ID,
PL_NO,
PL_NAME,
MAP_NO,
PNT_COUNT,
SURVEY_MAP_LINK,
SHAPE_TYPE,
PURPOSE,
LAND_TYPE,
PNT_SURVEY,
PNT_CHECKER,
DIKUAI_NO,
DIKUAI_AREA,
LAND_AREA,
AUTO_AREA,
FOR_PLACE,
REGIONCODE)
values
(newPL_ID,
NewFlowSN,
--oldSB_ID,--20090316
newSB_ID,
rBL_PLOT.PB_PB_ID,
rBL_PLOT.PL_NO,
rBL_PLOT.PL_NAME,
rBL_PLOT.MAP_NO,
rBL_PLOT.PNT_COUNT,
rBL_PLOT.SURVEY_MAP_LINK,
rBL_PLOT.SHAPE_TYPE,
rBL_PLOT.PURPOSE,
rBL_PLOT.LAND_TYPE,
rBL_PLOT.PNT_SURVEY,
rBL_PLOT.PNT_CHECKER,
rBL_PLOT.DIKUAI_NO,
rBL_PLOT.DIKUAI_AREA,
rBL_PLOT.LAND_AREA,
rBL_PLOT.AUTO_AREA,
rBL_PLOT.FOR_PLACE,
rBL_PLOT.REGIONCODE); --插入地块项目对应表
insert into bl_proj_plot
(flowsn, pj_id, pl_id)
values
(NewFlowSN, newPJ_ID, newPL_ID); --流程合并表记录对照表
insert into SourceVSBatch
(SourceFlowsn,
NewFlowsn,
Tablename,
Keyfields,
Sourcekeyvalues,
Newkeyvalues)
values
(aFlowSN(i),
NewFlowSN,
'BL_PLOT',
'PL_ID',
rBL_PLOT.PL_ID,
newPL_ID); FOR rBl_PLOT_USE IN cBl_PLOT_USE(oldPL_ID) LOOP
--插入地块用途面积
select S_Bl_PLOT_USE.NEXTVAL || SeqBaseCode
into newUSE_ID
from dual; insert into Bl_PLOT_USE
(USE_ID, FLOWSN, PL_ID, USENAME, USEAREA)
values
(newUSE_ID,
NewFlowSN,
newPL_ID,
rBl_PLOT_USE.USENAME,
rBl_PLOT_USE.USEAREA);
END LOOP;
--从土地分类面积表主表游标获取该旧地块的分类面积主表记录,并逐记录处理
--界址点成果表,PCD_ID用序列取值,PL_ID用新的地块ID,SB_SB_ID用新的勘测ID,其他字段用原来的值
insert into BL_PNT_COORD
(PCD_ID,
PL_ID,
SB_SB_ID,
PB_PB_ID,
PNT_NO,
X_COORD,
Y_COORD,
BORDER_LENGTH,
MATERIAL,
REMARK,
COORD_FALG,
SHAPE_GROUP,
PNT_SERIAL)
select s_BL_PNT_COORD.Nextval || SeqBaseCode,
newPL_ID,
newSB_ID,
PB_PB_ID,
PNT_NO,
X_COORD,
Y_COORD,
BORDER_LENGTH,
MATERIAL,
REMARK,
COORD_FALG,
SHAPE_GROUP,
PNT_SERIAL
from BL_PNT_COORD
where PL_ID = oldPL_ID; --从旧地块获取记录插入新地块记录
end loop;
end loop;