Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Другие СУБД > Конструкция id IN (select id from..... - тормозит


Автор: mixb 13.4.2006, 10:26
Возникла проблема в Paradox (работаю через BDE в TRxQuery Delphi5) :

- конструкция
Код
select * from table1 where id IN (select id from table2 where x = 1) 

очень долго (несколько минут) выполняется, причем вот такая конструкция:
Код
select * from table1 where id IN (1,2,3,4,5,6,...) 

работает очень быстро

В table1 - 3000 записей в table2 - 5000 записей

Подозреваю что BDE каждый раз перевыполняет
Код
(select id from table2 where x = 1) 


Если вместо IN поставить "=" выполняется очень быстро
Может запрос (select id from table2 where x = 1) возвращаеть 0 записей но работает вся конструкция очень долго.

Использовать такой код:
Код
select distinct table1.* from table1, table2 where table2.ID = table1.ID and table2.x = 1 
- неподходит, так как:
на самом деле мне надо
Код
 DELETE from table1 where id IN (select id from table2 where x = 1)
.Но это опять таки выполняется долго очень.
Остается вариант выборки id из table2 ручками а затем подстановка в IN (id1,id2,...idn)

Что тут делать?


Автор: ТоляМБА 14.4.2006, 13:46
Оговорки: У меня нет Paradox, поэтому не знаю, катят ли там JOIN’ы – если не катят – дальше можешь не читать.
Если катят – переделай синтаксис, если надо – я передал просто суть.
Делал на MS SQL Server 2000. Почему попробовал с джоинами - потому что на курсах говорили что джоины работают БЫСТРЕЕ (что тебе собственно и надо), чем подзапросы. И ещё – я проверял на маленькой тестовой таблице, какая будет скорость на большой – не знаю, но попробуй, напиши результат.

Ворки:
Table10 – Field1 (разные буквы), idn(цифры от 1 до 10)
Table11 – Field2 (разные буквы, но в некоторых позициях писал ‘ff’), idn(цифры от 1 до 10)
Запрос на выборку:

Код

SELECT Table10.idn
FROM  Table10
INNER JOIN Table11
ON Table10.idn = Table11.idn
WHERE (Table11.Field2 = 'ff')


Запрос на удаление:

Код

DELETE Table10
FROM Table10
INNER JOIN Table11
ON Table10.idn = Table11.idn
WHERE (Table11.Field2 = 'ff')


После запроса на удаление в Table10 остались только записи с идешниками совпадающими с идешниками Table11, в которых значения Field2<>’ff’.

Автор: bas 14.4.2006, 14:12
В первом случае идет работа со списком который формируеться динамически (если есть индекс то он будет быстрее формироваться).
Во втором случае список сформирован.

Автор: Sqlninja 15.5.2006, 11:46
Убедись в том, что есть индекс для table2 по ID. 

Автор: mixb 16.8.2006, 10:11
Проблему решил через использование вспомогательной таблицы для подзапросов - в цикле while not query.EOF в строку записываю IDшники через запятую и потом в квадратные скобки и в SQL.

2Sqlninja,  - индексы первым делом проверил - все которые используются - в наличии. Может дело в каких то настройках BDE? 

2ТоляМБА, на SQL Server'e проблем с вложенными подзапросами мною не наблюдалось - и описываемая мной конструкция работала б.
Кстати при JOIN - случайно не удалятся записи из Table11?

2bas - список формируется динамически но есть подозрения что подзапрос выполняется не один раз а при проверке каждой записи. Такое может быть?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)