使用连接和多个选择优化Oracle查询

时间:2017-12-01 18:34:17

标签: sql oracle

我运行的查询在IDE中运行需要6到7秒,而当我通过Confluence插件运行它以将结果发布到wiki时,需要4-5倍。我对Oracle很新,而Over / Partition By部分是我从研究Stack Overflow中学到的东西。它让我得到了我想要的结果,但还不够快。

我想要实现的目标: 我们有一个测试库。每个测试每天运行多次。我需要每个测试的最新执行状态,执行日期和其他相关值。查询只返回4k记录,因此我认为它不应该花费多长时间。当在wiki上显示超过30秒(我们需要发布结果时,效率非常低。

我希望有人可以看看并帮助我优化这一点,并帮助我了解解决方案的内容。打破它并单独运行,速度问题肯定是过度/分区。

提前谢谢你。

const arr = csv.split(/\n/g).map(str => str.split(','));
const headings = arr.shift();
const xyz = arr.map(arr => {
  return { x: arr[17], y: arr[18], z: arr[19] };
});

2 个答案:

答案 0 :(得分:0)

我希望你有一个适当的加入索引,同时为了避免与太多的记录进行比较,我只是使用第一个表(run)来识别所需的东西,然后加入其他表。

这下面的sql可以帮助你,我不确定,只是告诉我它是否确实如此。

由于 Thangamani Eraniyan。

enter image description here

SELECT
    TS_USER_11                               AS "Team",
    TS_TEST_ID                               AS "Test ID",
    TS_NAME                                  AS "Test Name",
    TS_USER_06                               AS "Priority",
    CASE  
        WHEN RN_STATUS = 'Failed' OR RN_STATUS = 'Issue Found' THEN 'Ran with Issues'
        WHEN RN_STATUS = 'No Run' AND RN_EXECUTION_DATE IS NOT NULL THEN 'Skipped'
        WHEN (RN_STATUS = 'No Run' OR RN_STATUS = 'N/A') AND RN_EXECUTION_DATE IS NULL THEN 'Not Run'
            ELSE RN_STATUS 
    END                       AS "Exec Status",       
    TS_USER_03                               AS "Type",
    TO_CHAR(RN_EXECUTION_DATE, 'YYYY-MM-DD') AS "Execution Date",
    RN_USER_01                               AS "Build Number"
    RN_RUN_ID,
FROM (SELECT RN_RUN_ID,
             RN_USER_01,
             row_number() OVER ( PARTITION BY RN_TEST_CONFIG_ID order by RN_RUN_ID desc  /* or if you have any run dt  desc*/  ) lno,
             RUN.RN_STATUS,
             RUN.RN_EXECUTION_DATE
       FROM  DATA_PROTECTION_HENDRIX_DB.RUN
     ) RUN 
LEFT JOIN DATA_PROTECTION_HENDRIX_DB.TEST ON RUN.RN_TEST_ID = TS_TEST_ID
LEFT JOIN DATA_PROTECTION_HENDRIX_DB.ALL_LISTS ON AL_ITEM_ID = TS_SUBJECT
WHERE RUN.LNO =1 
     (ALL_LISTS.AL_ABSOLUTE_PATH NOT LIKE 'AAAAAPAAJ%' AND ALL_LISTS.AL_ABSOLUTE_PATH NOT LIKE 'AAAAAPAAC%')  AND
     NVL(TS_TEMPLATE ,'N') = 'N'

答案 1 :(得分:0)

您应该在(Run.rn_test_config_id, Run.rn_run_id) AND (Run.rn_run_id)上设置索引,这应该有助于分区和后续加入。

我也可能会看到调整这样的查询是否会有所帮助:

SELECT  Test.ts_user_11 AS "Team", 
        Test.ts_test_id AS "Test ID",
        Test.ts_name AS "Test Name",
        TEST.ts_user_06 AS "Priority",
        CASE WHEN Run.rn_status = 'Failed' OR Run.rn_status = 'Issue Found' 
                  THEN 'Ran with Issues'
             WHEN Run.rn_status = 'No Run' AND Run.rn_execution_date IS NOT NULL 
                  THEN 'Skipped'
             WHEN (Run.rn_status = 'No Run' OR Run.rn_status = 'N/A') AND Run.rn_execution_date IS NULL 
                  THEN 'Not Run'
             ELSE Run.rn_status END AS "Exec Status",
        Test.ts_user_03 AS "Type",
        TO_CHAR(Run.rn_execution_date, 'YYYY-MM-DD') AS "Execution Date",
        Run.rn_user_01 AS "Build Number"  
FROM Data_Protection_Hendrix_DB.Run Run
-- one of the few times you can exclude the grouping condition from the results!
-- Only since rn_run_id is distinct
JOIN (SELECT MAX(rn_run_id) AS run_id
      FROM Data_Protection_Hendrix_DB.Run
      GROUP BY rn_test_config_id) Latest_Run
  ON Latest_Run.run_id = Run.rn_run_id
-- kept these as a LEFT JOIN, since that's more likely the intent.
-- I'm not sure that's what you were _getting_, though.
LEFT JOIN Data_Protection_Hendrix_DB.Test
       ON Test.ts_test_id = Run.rn_test_id
          AND Test.ts_template = 'N'
LEFT JOIN Data_Protection_Hendrix_DB.All_Lists
       ON All_Lists.al_item_id = Test.ts_subject
          AND All_Lists.al_absolute_path NOT LIKE 'AAAAAPAAJ%'
          AND All_Lists.al_absolute_path NOT LIKE 'AAAAAPAAC%'