Строка доступа к таблице не работает в этом запросе - PullRequest
0 голосов
/ 09 июля 2020

Я хочу избежать TABLE ACCESS FULL в плане выполнения, но он не работает, даже когда я принудительно использую index / * index () * / в этом запросе:

SELECT 
    af.ID, af.nom_flux, st.chemin_stockage, af.hash_flux 
FROM 
    stockage st 
INNER JOIN 
    allotissement_flux af  ON EXISTS (SELECT *
                                      FROM signature sig
                                      WHERE st.id_flux = sig.id_flux
                                        AND af.ID = sig.id_flux
                                        AND sig.statut_signature = 'SIGNE'
                                        AND sig.nb_appel_service_signature < 4 
                                        AND sig.date_statut_signature >= sysdate - 1000)
WHERE 
    st.statut_stockage = 'OUI'
    AND st.date_statut_stockage >= sysdate - 1000 

Индекс создается на каждый атрибут таблиц.

Plan hash value: 2782848463
 
---------------------------------------------------------------------------------------------------
| Id  | Operation            | Name               | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |                    |    40M|  8376M|       |  1594K  (1)| 00:01:03 |
|*  1 |  HASH JOIN           |                    |    40M|  8376M|  4284M|  1594K  (1)| 00:01:03 |
|*  2 |   HASH JOIN          |                    |    40M|  3821M|  1505M|   543K  (1)| 00:00:22 |
|   3 |    SORT UNIQUE       |                    |    40M|  1042M|       |   146K  (1)| 00:00:06 |
|*  4 |     TABLE ACCESS FULL| SIGNATURE          |    40M|  1042M|       |   146K  (1)| 00:00:06 |
|*  5 |    TABLE ACCESS FULL | STOCKAGE           |    48M|  3322M|       |   130K  (2)| 00:00:06 |
|   6 |   TABLE ACCESS FULL  | ALLOTISSEMENT_FLUX |    49M|  5527M|       |   536K  (1)| 00:00:21 |
---------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   1 - access("AF"."ID"="SIG"."ID_FLUX")
   2 - access("ST"."ID_FLUX"="SIG"."ID_FLUX")
   4 - filter("SIG"."NB_APPEL_SERVICE_SIGNATURE"<4 AND "SIG"."STATUT_SIGNATURE"='SIGNE' 
              AND "SIG"."DATE_STATUT_SIGNATURE">=SYSDATE@!-1000)
   5 - filter("ST"."STATUT_STOCKAGE"='OUI' AND "ST"."DATE_STATUT_STOCKAGE">=SYSDATE@!-1000)

Ответы [ 3 ]

1 голос
/ 09 июля 2020

EXISTS в условии JOIN не даст вам хорошей производительности.

Следует использовать простые условия соединения. Попробуйте следующее:

SELECT af.ID, af.nom_flux, st.chemin_stockage, af.hash_flux 
FROM stockage st 
INNER JOIN allotissement_flux af 
   ON af.ID = st.id_flux -- join condition
WHERE st.id_flux IN ( SELECT sig.id_flux --moved this logic in WHERE clause
        FROM signature sig
        WHERE sig.statut_signature = 'SIGNE'
        AND sig.nb_appel_service_signature < 4 
        AND sig.date_statut_signature >= sysdate - 1000
        )
AND st.statut_stockage = 'OUI'
AND st.date_statut_stockage >= sysdate - 1000 
1 голос
/ 09 июля 2020

Я бы начал с обычной формулировки join:

SELECT af.ID, af.nom_flux, st.chemin_stockage, af.hash_flux 
FROM signature sig JOIN
     stockage st 
     ON st.id_flux = sig.id_flux JOIN
     allotissement_flux af 
     ON af.ID = sig.id_flux
WHERE sig.statut_signature = 'SIGNE' AND
      sig.nb_appel_service_signature < 4 
      sig.date_statut_signature >= sysdate - 1000 AND
      st.statut_stockage = 'OUI' AND
      st.date_statut_stockage >= sysdate - 1000;

Неясно, какие индексы будут работать лучше, но следует учитывать следующее:

  • signature(statut_signature, date_statut_signature, nb_appel_service_signature, id_flux)
  • stockage(statut_stockage, date_statut_stockage, id_flux)
  • allotissement_flux(id) - вероятно, у вас уже есть этот
0 голосов
/ 09 июля 2020

Самый простой способ: используйте параметр '+ outline' в параметре формата dbms_xplan - он покажет вам раздел схемы, где вы можете взять подсказки схемы, изменить необходимые и добавить как подсказки.

PS. Не рекомендуется использовать exists () в разделе ON - CBO преобразует синтаксис ANSI в собственный собственный синтаксис, поэтому ваши подсказки могут стать недействительными.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...