2012-06-27 2 views
2

У меня есть две таблицы, одна маленькая (~ 400 строк), одна большая (~ 15 миллионов строк), и я пытаюсь найти записи из маленькой таблицы, у которой нет связанная запись в большой таблице.Ошибка производительности с выбором запроса в Firebird

Я столкнулся с массовые проблемы с производительностью с запросом.

Этот запрос:

SELECT * FROM small_table WHERE NOT EXISTS 
    (SELECT NULL FROM large_table WHERE large_table.small_id = small_table.id) 

Столбец large_table.small_id ссылки small_table-х id поле, которое является его первичным ключом. План запроса показывает, что внешний индекс ключ используется для large_table:

PLAN (large_table (RDB$FOREIGN70)) 
PLAN (small_table NATURAL) 

Статистика пересчитаны для индексов на обеих таблицах.

Выполнение запроса занимает несколько часов. Ожидается ли это?

  • Если да, могу ли я переписать запрос так, чтобы он был быстрее?
  • Если нет, что может быть неправильным?

ответ

0

Я не уверен в Firebird, но в других БД часто соединение происходит быстрее.

SELECT * 
FROM  small_table st 
LEFT JOIN large_table lt 
ON  st.id = lt.small_id 
WHERE  lt.small_id IS NULL 

Возможно, попробуйте?

Другой вариант, если вы действительно застряли, и в зависимости от ситуации, в которой это должно быть выполнено, следует взять столбец small_id из большой_таблицы, возможно, в таблицу temp, а затем выполнить левое соединение/EXISTS.

0

Если большая таблица имеет только относительно небольшое число различных значений для small_id, следующая будет работать лучше:

select * 
from small_table st left outer join 
    (select distinct small_id 
     from large_table 
    ) lt 
    on lt.small_id = st.id 
where lt.small_id is null 

В этом случае производительность будет лучше делать полную проверку большого стола, а затем индексный поиск в маленькой таблице - противоположность тому, что он делает. Выполнение отдельного может сделать только сканирование индекса на большой таблице, которая затем использует индекс первичного ключа на маленькой таблице.

Смежные вопросы