日期:2014-05-17  浏览次数:20912 次

问2个性能相关的问题
问2个性能相关的问题,谢谢了。

1.在存储过程中,需要向D表插入N条数据,而这些数据是根据A表、B表、C表编辑出来的(SQL文比较复杂,包括GROUP   BY等),可以通过两种方法来实现,一种是INSERT   INTO   D表   (字段1,字段2,…)   SELECT   ……   ;一种是通过游标,编辑一条,插入一条的方法来实现。请问这两种方法各有什么好处,那个性能最优?

2.
SQL文1:
SELECT  
    AA,BB,CC
FROM
    (
    SELECT
        AA,BB,CC
    FORM
        TABLE1
    WHERE
        AA= '1 '
    )   TABLE2

SQL文2:
SELECT  
    AA,BB,CC
FROM
    (
    SELECT
        AA,BB,CC
    FORM
        TABLE1
    )   TABLE2
WHERE
    AA= '1 '
请问SQL文1和SQL文2那个性能比较好,为什么?

3.
SQL文1:
SELECT  
    AA,BB,CC
FROM
    TABLE1
WHERE
    AA   =   '1 '   OR   BB   <   '10 '

SQL文2:
SELECT  
    AA,BB,CC
FROM
    TABLE1
WHERE
    BB   <   '10 '   OR   AA   =   '1 '

请问SQL文1和SQL文2那个性能比较好,为什么?

------解决方案--------------------
1.通常来说 是使用批插入 Select 比较快,但是有个别特殊情况。

2. SQL1 和 SQL2 性能相当

3. 在没有索引的情况下,就要看哪个条件过滤的记录多性能就好些,查询条件顺序从
右到左。如果都有索引,则性能都相当。
------解决方案--------------------
1.批量插入要快的多,除非有很特殊的处理尽量不要用存储过程,另外插入前可以把要插入表的主键和索引失效掉,这样插入的时候不需要维护索引会快很多;
2.两个语句性能差不多,但楼主的语句好像没必要, SELECT
AA,BB,CC
FORM
TABLE1
WHERE
AA= '1 '
这一层不就可以查出来了嘛?干吗费2遍事呢??
3.where子句的解析是从下到上的,楼主可以参考如下答复:

4. 选择最有效率的表名顺序(只在基于规则的优化器中有效)


ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,因此FROM子句中写在最后的表(基础表 driving table)将被最先处理. 在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表.当ORACLE处理多个表时, 会运用排序及合并的方式连接它们.首先,扫描第一个表(FROM子句中最后的那个表)并对记录进行派序,然后扫描第二个表(FROM子句中最后第二个表),最后将所有从第二个表中检索出的记录与第一个表中合适记录进行合并.


例如:

表 TAB1 16,384 条记录

表 TAB2 1 条记录


选择TAB2作为基础表 (最好的方法)

select count(*) from tab1,tab2 执行时间0.96秒


选择TAB2作为基础表 (不佳的方法)

select count(*) from tab2,tab1 执行时间26.09秒


如果有3个以上的表连接查询, 那就需要选择交叉表(intersection table)作为基础表, 交叉表是指那个被其他表所引用的表.


例如:

EMP表描述了LOCATION表和CATEGORY表的交集.

SELECT *

FROM LOCATION L ,

CATEGORY C,

EMP E

WHERE E.EMP_NO BETWEEN 1000 AND 2000

AND E.CAT_NO = C.CAT_NO

AND E.LOCN = L.LOCN


将比下列SQL更有效率


SELECT *

FROM EMP E ,

LOCATION L ,

CATEGORY C

WHERE E.CAT_NO = C.CAT_NO

AND E.LOCN = L.LOCN

AND E.EMP_NO BETWEEN 1000 AND 2000


5. WHERE子句中的连接顺序.


ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾.


例如:

(低效,执行时间156.3秒)

SELECT …

FROM EMP E

WHERE SAL > 50000

AND JOB = ‘MANAGER '

AND 25 < (SELECT COUNT(*) FROM EMP

WHERE MGR=E.EMPNO);


(高效,执行时间10.6秒)

SELECT …

FROM EMP E

WHERE 25 <