Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

SQL-запрос. [D6, MSSQL]


D-NICKNAME ©   (2002-12-22 11:07:00) 

Народ, помогите с оптимизацией SQL-запроса.
У меня есть таблица Main_General_Table, состоящая из 27тыс строк. В этой таблице есть колонки internal_number и external_number. Мне нужно заполнить таблицу Main_Summary_Table (в которой есть колонка number) от Main_General_Table по правилу:
из Main_General_Table берёт уникальное число internal_number, а external_number не должен начинаться с "8".
Написал такую хранимую процедуру (сразу оговорюсь, что до этой задачи с хранимыми процедурами не работал):

create procedure Create_Summary_Table @minsec int
as
declare @count_row int, @count_row2 int, @MGT_intnum varchar(30), @MGT_extnum varchar(30), @MST_intnum varchar(30), @MST_quantity int, @MGT_rhour int, @MGT_rminute int, @MGT_rsecond int, @temp_double real, @MST_duration real
declare cur cursor forward_only for select internal_number, external_number, r_hour, r_minute, r_second from Main_General_Table
delete from Main_Summary_Table

/*Создание таблицы уникальных номеров*/
select @count_row = count(internal_number) from Main_General_Table
open cur
while @count_row > 0 begin
fetch from cur into @MGT_intnum, @MGT_extnum, @MGT_rhour, @MGT_rminute, @MGT_rsecond
if (@MGT_intnum not in (select number from Main_Summary_Table)) and (@MGT_extnum not in (select external_number from Main_General_Table where external_number like "8%"))
insert into Main_Summary_Table (number) values(@MGT_intnum)
set @count_row = @count_row - 1
end
close cur
deallocate cur
go


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

Заранее благодарю.


D-NICKNAME   (2002-12-24 18:45:00) [1]

Всем спасибо!
Разобрался, оказывается в одну строчку можно весь запрос написать и выполняется в рекордно короткий срок.


stone   (2002-12-23 10:11:00) [2]

1. Конструкции с inпри больших объемах данных работатют относительно долго, лучше использовать exists (not exists)
2. Раз уж вы используете курсоры:
select @count_row = count(internal_number) from Main_General_Table - занимает лишнее время.
Правильнее:
open cur
fetch next from cur into @MGT_intnum, @MGT_extnum, @MGT_rhour, @MGT_rminute, @MGT_rsecond
while @@FETCH_STATUS = 0
begin
... действия
fetch next from cur into @MGT_intnum, @MGT_extnum, @MGT_rhour, @MGT_rminute, @MGT_rsecond
end;

3. Следует переделать и сам запрос (выбрки) вставки, но детально разбираться желания нет.


ЮЮ   (2002-12-23 05:27:00) [3]

Для начала попробу сам запрос:
select internal_number, external_number, r_hour, r_minute, r_second from Main_General_Table
where external_number not in
(select distinctexternal_number from Main_General_Table where external_number like "8%")
order by internal_number

Если выполняется в приемлемое время, то используй его вместо
fetch from cur ...,
а вместо
if (@MGT_intnum not in (select number from Main_Summary_Table))
используй, например, следующий алгоритм:
set @curent_internal = -1
...
if @MGT_intnum <> @curent_internal BEGIN
set @curent_internal = @MGT_intnum
<твоя обработка>
END



Если же долго, то оптимизировать, ИМХО, следует in (select...). Но это уже другая история :0)


Наверх

Титульная страница Поиск, карта сайта Написать письмо