字符“ A”是Oracle数据库中的保留关键字吗?

时间:2018-06-29 13:46:50

标签: sql oracle oracle12c query-performance

场景: 在Oracle数据库中,此SQL慢得多:

SELECT * 
FROM TBL_MAIN A, TBL_CHILD_1 B, TBL_CHILD_2 C, TBL_CHILD_3 D, TBL_CHILD_4 E
WHERE A.ID_MAIN = B.ID_MAIN 
AND A.ID_MAIN = C.ID_MAIN 
AND A.ID_MAIN = D.ID_MAIN 
AND A.ID_MAIN = E.ID_MAIN;

比那

SELECT * 
FROM TBL_MAIN X, TBL_CHILD_1 B, TBL_CHILD_2 C, TBL_CHILD_3 D, TBL_CHILD_4 E
WHERE X.ID_MAIN = B.ID_MAIN 
AND X.ID_MAIN = C.ID_MAIN 
AND X.ID_MAIN = D.ID_MAIN 
AND X.ID_MAIN = E.ID_MAIN;

换句话说,如果我使用“ A”作为“ TBL_MAIN”表的别名,则当我连接了3个或更多表时,这将导致查询速度变慢。

当我在内部联接中使用表“ TBL_MAIN” AS“ A”添加更多表时,情况变得最糟。

发生了什么事?

5 个答案:

答案 0 :(得分:3)

是的。它是一元收集运算符“ IS A SET”的一部分。在Oracle中,它有点复杂,为了保证向后兼容性,Oracle具有“保留字”和“关键字”。其中的一个不能用作标识符,而另一些可能具有特殊含义的是某些上下文-但仍可以用作标识符。

例如,您仍然可以像使用SQL

select * from commit;
or
select * from join where X is a set;

诸如提交,联接,模型之类的词仍然可以用作标识符。

当然这不会影响SQL评估的速度。特别是在游标被重用时。这可能只会减慢解析速度。

答案 1 :(得分:2)

我发现X实际上比A快,但是Z甚至更慢:

Alias A 60.257 seconds
Alias X 57.747 seconds
Alias Y 58.383 seconds
Alias Z 62.157 seconds

说实话,这些差异很小,无法证明别名之间的差异。

我用5个大表(tbl_main 2200万,tbl_child 1700万等)对其进行了测试。然后将SELECT *更改为SELECT COUNT(*),以确保所有行都已处理。将忽略第一次执行以预热缓存。接下来的三轮是平均。

DECLARE
  FUNCTION test1(c VARCHAR2) RETURN NUMBER IS
    time1 NUMBER; time2 NUMBER; stmt VARCHAR2(3000); n NUMBER;
  BEGIN
    stmt := q'!
      SELECT count(*)
        FROM tbl_main #, tbl_child1 B, tbl_child2 C, tbl_child3 D, tbl_child4 E
       WHERE #.geb_id = B.geb_id
         AND #.geb_id = C.geb_id
         AND #.geb_id = D.geb_id
         AND #.geb_id = E.geb_id
    !';
    stmt := REPLACE(stmt, '#', c);  
    --dbms_output.put_line(stmt);
    time1 := dbms_utility.get_time(); 
    EXECUTE IMMEDIATE stmt INTO n;
    time2 := dbms_utility.get_time(); 
    return (time2-time1)/100;
  END test1;

  PROCEDURE test3(c VARCHAR2) IS
    ignore NUMBER; seconds NUMBER;
  BEGIN
    ignore := test1(c);
    seconds := (test1(c)+test1(c)+test1(c)) / 3;
    DBMS_OUTPUT.PUT_LINE('Alias '||c||' '||round(seconds,3)||' seconds');
  END test3;
BEGIN
  test3('A');
  test3('X');
  test3('Y');
  test3('Z');
END;
/

答案 2 :(得分:2)

是的。在12c。

SELECT KEYWORD
FROM V$RESERVED_WORDS
WHERE KEYWORD = 'A'
;

答案 3 :(得分:0)

简答号。 A不是保留字。如果它是保留字,则会引发错误。但是,要分析性能问题,您需要发布指标以执行查询。

答案 4 :(得分:0)

问题解决了! 现在,两个SQL具有相同的时间,就像@wolφi所说的那样快一点。

这种情况持续了两天,但现在已经正常了。

我相信在关闭数据库后,数据库会恢复正常。

一个有趣的事情是,当问题发生时,SQL Tuning Advisor提出了使正常工作的SQL的执行计划(加快了99.9%)。不幸的是,我当时没有保存推荐报告以在此处显示。

但是现在没有任何有效的SQL配置文件,这些SQL具有相同的时间。