oracle SQL耗时太长,如何优化此查询?

kyxcudwk  于 2023-05-16  发布在  Oracle
关注(0)|答案(1)|浏览(175)

这个查询的问题是太慢了:

SELECT
   *
FROM
(
      SELECT
         *
      FROM
(
            SELECT
               *
            FROM
               (
                  SELECT
                     *
                  FROM
                     (
                        SELECT
                           *
                        FROM
                           (
                              SELECT
                                 MIN(UPPER(MSG_USERS.MSU_LOGIN_NAME)) as MSU_LOGIN_NAME_SORT,
                                 MSG_USERS.MSU_USER_ID ID,
                                 MSG_USERS.MSU_LAST_LOGIN_TIME,
                                 MSG_USERS.MSU_CREATED_DATE,
                                 MSG_USERS.MSU_LOGIN_NAME,
                                 MSG_USERS.MSU_UUID,
                                 MSG_USERS.MSU_FIRST_NAME,
                                 MSG_USERS.MSU_LAST_NAME,
                                 MSG_USERS.MSU_LAST_UPDATED,
                                 MSG_USERS.MSU_CUSTOMER_UID
                              FROM
                                 (
                                    MSG_USERS
                                    left join MSG_ACCOUNT_USERS on MAU_USER_ID = MSU_USER_ID
                                    left join MSG_ACCOUNTS on MSA_ACCOUNT_ID = MAU_ACCOUNT_ID
                                    left join MSG_TENANTS on MTE_ACCOUNT_ID = MAU_ACCOUNT_ID
                                 )
                              WHERE
                                 (
                                    MSG_USERS.MSU_ROLE_NAME <> 'CUSTOMER_INTEGRATION'
                                    AND MSG_USERS.MSU_ROLE_NAME <> 'CUSTOMER_EXTERNAL_INTEGRATION'
                                    AND MSG_USERS.MSU_ROLE_NAME <> 'INTEGRATION_SUPERUSER'
                                    AND MSG_USERS.MSU_ROLE_NAME <> 'OAUTH2_CLIENT'
                                 )
                              GROUP BY
                                 MSG_USERS.MSU_USER_ID,
                                 MSG_USERS.MSU_LAST_LOGIN_TIME,
                                 MSG_USERS.MSU_CREATED_DATE,
                                 MSG_USERS.MSU_LOGIN_NAME,
                                 MSG_USERS.MSU_UUID,
                                 MSG_USERS.MSU_FIRST_NAME,
                                 MSG_USERS.MSU_LAST_NAME,
                                 MSG_USERS.MSU_LAST_UPDATED,
                                 MSG_USERS.MSU_CUSTOMER_UID
                              ORDER BY
                                 MIN(UPPER(MSG_USERS.MSU_LOGIN_NAME)) ASC
                           )
                        ORDER BY
                           UPPER(MSU_LOGIN_NAME_SORT) ASC,
                           ID ASC
                     )
                  WHERE
                     ROWNUM < 7
               )
            ORDER BY
               UPPER(MSU_LOGIN_NAME_SORT) DESC,
               ID DESC
         )
      WHERE
         ROWNUM < 7
   )
ORDER BY
   UPPER(MSU_LOGIN_NAME_SORT) ASC,
   ID ASC;

我不知道如何优化它。

s4n0splo

s4n0splo1#

原则上你有

select ...
from (((( ...
                              ORDER BY
                                 MIN(UPPER(MSG_USERS.MSU_LOGIN_NAME)) ASC
                           )
                        ORDER BY
                           UPPER(MSU_LOGIN_NAME_SORT) ASC,
                           ID ASC
                     )
                  WHERE
                     ROWNUM < 7
               )
            ORDER BY
               UPPER(MSU_LOGIN_NAME_SORT) DESC,
               ID DESC
         )
      WHERE
         ROWNUM < 7
   )
ORDER BY
   UPPER(MSU_LOGIN_NAME_SORT) ASC,
   ID ASC;

这条疯狂的锁链的目的是什么?
您使用表MSG_ACCOUNT_USERS, MSG_ACCOUNTS, MSG_TENANTS生成LEFT JOIN,但它们未在查询中使用。你为什么要加入他们呢?它们没有任何作用,我猜你可以简单地从查询中删除它们,然后你甚至不需要GROUP BY子句。
我假设您的查询可以简化为这样的内容:

SELECT
   MSG_USERS.MSU_USER_ID ID,
   MSG_USERS.MSU_LAST_LOGIN_TIME,
   MSG_USERS.MSU_CREATED_DATE,
   MSG_USERS.MSU_LOGIN_NAME,
   MSG_USERS.MSU_UUID,
   MSG_USERS.MSU_FIRST_NAME,
   MSG_USERS.MSU_LAST_NAME,
   MSG_USERS.MSU_LAST_UPDATED,
   MSG_USERS.MSU_CUSTOMER_UID
FROM MSG_USERS
WHERE MSG_USERS.MSU_ROLE_NAME NOT IN ('CUSTOMER_INTEGRATION' 'CUSTOMER_EXTERNAL_INTEGRATION' 'INTEGRATION_SUPERUSER' 'OAUTH2_CLIENT')
ORDER BY ...
FETCH FIRST 7 ROWS ONLY;

相关问题