SQL-запрос занимает много времени

Приведенный ниже запрос занимает много времени, и я пытаюсь настроить запрос, но, похоже, он не работает. В любом случае я могу переписать запрос. Пожалуйста, помогите мне настроить запрос.

 SELECT DISTINCT TC.V_ID,A.ID,A.NAME 
    FROM OM_A_DATA TC 
       INNER JOIN ACC_DOM_EXT AE ON TC.DOMAINS = AE.DOMAIN
        LEFT OUTER JOIN ACCOUNT A ON A.ID=AE.ACCOUNTID
    WHERE V_ID not in (select distinct V_ID from DATA_ACC_MAP)


OM_A_DATA  has 41,696,776 rows
ACC_DOM_EXT has 106,725 rows
ACCOUNT has 106731 rows
DATA_ACC_MAP has 91021 rows          

person MKN    schedule 02.11.2015    source источник
comment
Нет необходимости выбирать DISTINCT в подзапросе.   -  person jarlh    schedule 02.11.2015
comment
Определены ли столбцы V_ID NOT NULL?   -  person William Robertson    schedule 10.12.2015


Ответы (2)


Часто not exists работает лучше, чем not in:

SELECT DISTINCT TC.V_ID, A.ID, A.NAME 
FROM OM_A_DATA TC INNER JOIN
     ACC_DOM_EXT AE
     ON TC.DOMAINS = AE.DOMAIN LEFT OUTER JOIN
     ACCOUNT A
     ON A.ID = AE.ACCOUNTID
WHERE NOT EXISTS (SELECT 1 FROM DATA_ACC_MAP dam WHERE dam.V_ID = tc.V_ID );

Ясно, что у вас должен быть указатель на DATA_ACC_MAP(V_ID). У вас также должны быть индексы для других столбцов: OM_A_DATA(V_ID, DOMAINS), ACC_DOM_EXT(DOMAIN, ACCOUNTID) и ACCOUNT(ID, NAME).

person Gordon Linoff    schedule 02.11.2015

Либо удалите DISTINCT.

SELECT DISTINCT TC.V_ID, A.ID, A.NAME 
FROM OM_A_DATA TC 
INNER JOIN ACC_DOM_EXT AE ON TC.DOMAINS = AE.DOMAIN
LEFT OUTER JOIN ACCOUNT A ON A.ID = AE.ACCOUNTID
WHERE V_ID NOT IN (SELECT V_ID FROM DATA_ACC_MAP)

Или используйте INNER JOIN, а не подзапрос.

SELECT DISTINCT TC.V_ID, A.ID, A.NAME 
FROM OM_A_DATA TC 
INNER JOIN ACC_DOM_EXT AE ON TC.DOMAINS = AE.DOMAIN
INNER JOIN DATA_ACC_MAP AD ON TC.V_ID != AD.V_ID 
LEFT OUTER JOIN ACCOUNT A ON A.ID = AE.ACCOUNTID

Или используйте LEFT JOIN вместо подзапроса и измененного предложения WHERE.

SELECT DISTINCT TC.V_ID, A.ID, A.NAME 
FROM OM_A_DATA TC 
INNER JOIN ACC_DOM_EXT AE ON TC.DOMAINS = AE.DOMAIN
LEFT JOIN DATA_ACC_MAP AD ON TC.V_ID = AD.V_ID 
LEFT OUTER JOIN ACCOUNT A ON A.ID = AE.ACCOUNTID
WHERE AD.V_ID IS NULL
person Matt    schedule 02.11.2015