查询有时无法执行。还有其他选择吗?

时间:2012-03-13 07:07:10

标签: sql oracle oracle11g oracle-sqldeveloper

我有一个自动化的SQL脚本,运行时执行以下代码

DROP TABLE INTL_KEY;
CREATE TABLE intl_key AS
SELECT callingpartynumber||calledpartynumber||timeandtimezonestartofcharging AS KEY,a.*   FROM intl a;

基本上,它是 INTL 表的副本,带有主键字段。

在此之后,立即执行以下代码。

CREATE TABLE intl_code as
SELECT a.*,b.code FROM intl_key a, country_code b WHERE SubStr(calledpartynumber,3,12)=code
union
SELECT a.*,b.code FROM intl_key a, country_code b WHERE SubStr(calledpartynumber,3,11)=code
union
SELECT a.*,b.code FROM intl_key a, country_code b WHERE SubStr(calledpartynumber,3,10)=code
union
SELECT a.*,b.code FROM intl_key a, country_code b WHERE SubStr(calledpartynumber,3,9)=code
union
SELECT a.*,b.code FROM intl_key a, country_code b WHERE SubStr(calledpartynumber,3,8)=code
union
SELECT a.*,b.code FROM intl_key a, country_code b WHERE SubStr(calledpartynumber,3,7)=code
UNION
SELECT a.*,b.code FROM intl_key a, country_code b WHERE SubStr(calledpartynumber,3,6)=code
union
SELECT a.*,b.code FROM intl_key a, country_code b WHERE SubStr(calledpartynumber,3,5)=code
union
SELECT a.*,b.code FROM intl_key a, country_code b WHERE SubStr(calledpartynumber,3,4)=code
union
SELECT a.*,b.code FROM intl_key a, country_code b WHERE SubStr(calledpartynumber,3,3)=code
UNION
SELECT a.*,b.code FROM intl_key a, country_code b WHERE SubStr(calledpartynumber,3,2)=code
UNION
SELECT a.*,b.code FROM intl_key a, country_code b WHERE SubStr(calledpartynumber,3,1)=code

本节的目的是创建 INTL_KEY 的副本,并添加代码的列。其他表 Country_Code 中的国家/地区代码与 INTL_KEY 中的已拨号码相匹配。

示例如果拨打的号码 00912886098860 它会搜索从91xxxxxxxxxx到9的国家/地区代码。现在问题是,假设有效代码是 912 ,它将首先与

匹配
SELECT a.*,b.code FROM intl_key a, country_code b WHERE SubStr(calledpartynumber,3,3)=code

然而, 91 也是一个有效的代码。因此它也将与

匹配
SELECT a.*,b.code FROM intl_key a, country_code b WHERE SubStr(calledpartynumber,3,2)=code

为了删除此重复匹配,下一位代码是

DELETE FROM intl_code WHERE ROWID NOT IN (SELECT Min(rowid) FROM intl_code GROUP BY KEY );

保留先匹配的对象,然后删除后续匹配。这是问题发生的地方。有时,语句将无法执行/花费很长时间。 (查询是通过VPN运行的,所以有时会超时,有时如果表空间太大而无法运行等)

我想知道是否有办法优化我想做的事情。如果是这样,我将不胜感激任何帮助。就像创建一个只有最小rowid行的新表一样?

如果它有助于理解事物的规模,平均每天创建300,000个新行,每行有大约50个以上的字段。 (这是每天特定国家的运营商的国际电话数量)

1 个答案:

答案 0 :(得分:1)

我认为您可以在创建intl_code表时合并这些不同的查询。

这意味着你可以像

那样写作
CREATE TABLE intl_code as
SELECT a.*,b.code 
  FROM intl_key a, country_code b 
 WHERE SubStr(calledpartynumber,3,12)=code
    or SubStr(calledpartynumber,3,11)=code 
    or SubStr(calledpartynumber,3,10)=code
    or SubStr(calledpartynumber,3,9)=code
    or SubStr(calledpartynumber,3,8)=code
    or SubStr(calledpartynumber,3,7)=code
    or SubStr(calledpartynumber,3,6)=code
    or SubStr(calledpartynumber,3,5)=code
    or SubStr(calledpartynumber,3,4)=code
    or SubStr(calledpartynumber,3,3)=code
    or SubStr(calledpartynumber,3,2)=code
    or SubStr(calledpartynumber,3,1)=code;

这样从表连接intl_key a, country_code b获取数据时只会发生一次..它也会提供与之前联合查询相同的行。

基本上这个查询花费的时间大约是你用Union获得的N倍...​​我告诉的是union关键字不是问题..但如果你加入两个大表,那么你可以使用多个条件代替多个连接..

试试这个......