2017-10-15 74 views
-1

我的项目中有一个SQL查询,每次花费10s +。SQL查询花费的时间至少为10s

SELECT * FROM (
    SELECT TP.TOPIC_ID, CK.NAME 
    FROM TD_TOPIC TP 
    INNER JOIN TD_CIRCLE CK on CK.CIRCLE_ID = TP.CIRCLE_ID AND CK.VALID = 1 AND SYSDATE > CK.EFF_TIME 
    WHERE 
     TP.VALID = 1 AND TP.FORWARD_FROM_TOPIC_ID = 0 
     AND ((TP.TOPIC_TYPE = 1 AND TP.APPROVAL_STATUS = 1) OR TP.TOPIC_TYPE IN (0, 2)) 
     AND (TP.TOPIC_TYPE != 2 OR EXISTS (
       SELECT 1 FROM TD_VOTE_TOPIC_CONFIG CFG 
       WHERE CFG.TOPIC_ID=TP.TOPIC_ID AND SYSDATE > CFG.EFFECT_TIME 
     )) 
     AND (
      EXISTS (
        SELECT 1 FROM TD_TOPIC_TAG TG WHERE TG.TOPIC_ID=TP.TOPIC_ID 
        AND TG.TAG_ID IN (1, 2) 
      ) 
      OR EXISTS (
       SELECT 1 FROM TD_CIRCLE_TAG CTG WHERE CTG.CIRCLE_ID=CK.CIRCLE_ID 
        AND CTG.TAG_ID IN (1, 2) 
      ) 
     ) 
    ORDER BY TP.CREATE_TIME DESC 
) WHERE ROWNUM<21 

ER

这是查询计划。 TP_TOPICTABLE FULL ACCESS需要太多时间。

3 ------------------------------------------------------------------------------------------------------------- 
4 | Id | Operation      | Name      | Rows | Bytes | Cost (%CPU)| Time  | 
5 ------------------------------------------------------------------------------------------------------------- 
6 | 0 | SELECT STATEMENT     |       | 20 | 4560 | 4286 (1)| 00:00:52 | 
7 |* 1 | COUNT STOPKEY     |       |  |  |   |   | 
8 | 2 | VIEW       |       | 48986 | 10M| 4286 (1)| 00:00:52 | 
9 |* 3 | SORT ORDER BY STOPKEY   |       | 48986 | 6936K| 4286 (1)| 00:00:52 | 
10 | 4 |  CONCATENATION    |       |  |  |   |   | 
11 |* 5 |  FILTER      |       |  |  |   |   | 
12 |* 6 |  HASH JOIN     |       | 24516 | 3471K| 2140 (1)| 00:00:26 | 
13 |* 7 |  TABLE ACCESS FULL   | TD_CIRCLE    | 415 | 44820 | 11 (0)| 00:00:01 | 
14 |* 8 |  TABLE ACCESS FULL   | TD_TOPIC     | 75205 | 2717K| 2128 (1)| 00:00:26 | 
15 |* 9 |  TABLE ACCESS BY INDEX ROWID| TD_CIRCLE_TAG   |  1 |  8 |  2 (0)| 00:00:01 | 
16 |* 10 |  INDEX RANGE SCAN   | IDX_TD_CIRCLE_TAG_TAG_ID |  1 |  |  1 (0)| 00:00:01 | 
17 |* 11 |  TABLE ACCESS BY INDEX ROWID| TD_VOTE_TOPIC_CONFIG  |  1 | 13 |  2 (0)| 00:00:01 | 
18 |* 12 |  INDEX RANGE SCAN   | IDX_VTCFG_TOPICID  |  1 |  |  1 (0)| 00:00:01 | 
19 |* 13 |  FILTER      |       |  |  |   |   | 
20 |* 14 |  HASH JOIN     |       | 24516 | 3471K| 2140 (1)| 00:00:26 | 
21 |* 15 |  TABLE ACCESS FULL   | TD_CIRCLE    | 415 | 44820 | 11 (0)| 00:00:01 | 
22 |* 16 |  TABLE ACCESS FULL   | TD_TOPIC     | 75205 | 2717K| 2128 (1)| 00:00:26 | 
23 |* 17 |  TABLE ACCESS BY INDEX ROWID| TD_CIRCLE_TAG   |  1 |  8 |  2 (0)| 00:00:01 | 
24 |* 18 |  INDEX RANGE SCAN   | IDX_TD_CIRCLE_TAG_TAG_ID |  1 |  |  1 (0)| 00:00:01 | 
25 |* 19 |  TABLE ACCESS BY INDEX ROWID| TD_TOPIC_TAG    |  1 |  8 |  2 (0)| 00:00:01 | 
26 |* 20 |  INDEX RANGE SCAN   | IDX_TD_TOPIC_TAG_TAG_ID |  1 |  |  1 (0)| 00:00:01 | 
27 |* 21 |  TABLE ACCESS BY INDEX ROWID| TD_VOTE_TOPIC_CONFIG  |  1 | 13 |  2 (0)| 00:00:01 | 
28 |* 22 |  INDEX RANGE SCAN   | IDX_VTCFG_TOPICID  |  1 |  |  1 (0)| 00:00:01 | 
29 ------------------------------------------------------------------------------------------------------------- 

TD_TOPIC非常大。我发现TABLE ACCESS (FULL)TD_TOPIC。也许这是问题。但我不知道如何通过索引访问它。

+2

您有问题要问? –

+0

@Gordon Linoff我想改进它并使其更快。 – John

+0

您能否以文本格式生成解释格式,而不是位图?只需在'EXPLAIN PLAN FOR your query' - > [explain plan example](https://docs.oracle.com/cd/B28359_01/server.111/b28274/ex_plan.htm#i17492)前加上你的查询,运行这个命令,然后运行'SELECT * FROM table(Dbms_Xplan.display)',它将以文本格式生成解释。然后复制上次查询的全部结果并将其附加到问题中。 – krokodilko

回答

1
SELECT * 
    FROM (
      SELECT TP.TOPIC_ID, 
        CK.NAME 
      FROM TD_TOPIC TP 
     INNER JOIN TD_CIRCLE CK 
       ON CK.CIRCLE_ID = TP.CIRCLE_ID 
     LEFT JOIN TD_VOTE_TOPIC_CONFIG CFG 
       ON CFG.TOPIC_ID=TP.TOPIC_ID 
     LEFT JOIN TD_CIRCLE_TAG CTG 
       ON CTG.CIRCLE_ID=CK.CIRCLE_ID 
      WHERE TP.VALID = 1 
       AND TP.FORWARD_FROM_TOPIC_ID = 0 
       AND CK.VALID = 1 
       AND CK.EFF_TIME < SYSDATE 
       AND (
         ( 
          TP.TOPIC_TYPE = 1 
         AND TP.APPROVAL_STATUS = 1 
         ) 
        OR TP.TOPIC_TYPE IN (0, 2) 
       ) 
       AND ( 
         TP.TOPIC_TYPE != 2 
        OR 
         CFG.EFFECT_TIME < SYSDATE 
       ) 
       AND (
         (
          TG.TOPIC_ID IS NOT NULL 
         AND TG.TAG_ID IN (1, 2) 
         ) 
        OR 
        (
          CTG.CIRCLE_ID IS NOT NULL 
         AND CTG.TAG_ID IN (1, 2) 
         )   
       ) 
     ORDER BY TP.CREATE_TIME DESC 
     ) 
    WHERE ROWNUM<21