SQL查询的开销至少为10秒

时间:2017-10-15 03:59:40

标签: sql oracle

我的项目中有一个SQL查询每次花费10s +。

name = ['rob', 'mike', 'bob']
age = ['19', '32', '88']
id = ['aaa', 'bbb', 'ccc']
import csv
with open('eggs.csv', 'w', newline='') as csvfile:
    spamwriter = csv.writer(csvfile, delimiter=',',
                            quotechar='|', quoting=csv.QUOTE_MINIMAL)

    data = list(zip(name, age, id))
    for row in data:
        row = list(row)
        spamwriter.writerow(row)
print("Program completed")

ER

这是查询计划。 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 的{​​{1}}需要花费太多时间。

TABLE FULL ACCESS

TP_TOPIC非常大。我找到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 ------------------------------------------------------------------------------------------------------------- 的{​​{1}}。也许是问题所在。但我不知道如何通过索引访问它。

1 个答案:

答案 0 :(得分: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