Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Помогите оптимизировать и составить правильно запрос  [new]
MathewSun
Member

Откуда: Москва
Сообщений: 17
У меня три таблицы.
Таблица заказов (323 записи), таблица работников (1900 записей) и таблица выполненных заказов (58.000 записей).
Мне нужно взять работника, который еще не выполнял заказ и поставить ему задачу.

Запрос выглядит так:

declare @UserName nvarchar(50) = 'victor';
	
	select TOP 1 
	o.Id, 
	va.[Login], 
	o.[OrderType],
	from Orders o, [Accounts] va
	LEFT JOIN Users u
		ON u.UserId = va.UserId
	where 
	va.[IsActive] = 1 
	AND va.IsDeleted = 0
	AND o.IsDone = 0
	AND u.UserName = @UserName
	AND not exists (
		select 1 from OrderEvents oe 
		where 	va.[Login] = oe.Account 
				AND o.[Id] = oe.[OrderId]
	) 

	order by va.[LastActive], o.[LastUpdate]


Этот запрос по профайлеру выгребает 136.000 записей.

Причем без проверки
AND not exists (
		select 1 from OrderEvents oe 
		where 	va.[Login] = oe.Account 
				AND o.[Id] = oe.[OrderId]
				--AND o.[OrderType] = oe.[OrderType]
	)

он выгребает всего 210 записей.

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

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

Или здесь нужен индекс?

Заранее спасибо.
8 янв 16, 04:07    [18651652]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать и составить правильно запрос  [new]
aleks2
Guest
create index IDX_OrderEvents on OrderEvents ( Account, OrderId );

select top(1) 
	o.Id, 
	va.[Login], 
	o.OrderType
	from Orders o
        cross join 
        ( select top(1) va.[Login] 
            from Accounts va inner join Users u on u.UserId = va.UserId
            where va.IsActive = 1 and va.IsDeleted = 0 and u.UserName = @UserName 
        ) as X
	where 
	  o.IsDone = 0
	  and not exists ( select * from OrderEvents oe where va.[Login] = oe.Account and o.Id = oe.OrderId ) 
	order by va.LastActive, o.LastUpdate;
8 янв 16, 10:05    [18651849]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать и составить правильно запрос  [new]
iap
Member

Откуда: Москва
Сообщений: 47052
MathewSun,

не надо мешать запятую и JOIN во FROMе.
Замените запятую на CROSS JOIN
8 янв 16, 11:28    [18651979]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать и составить правильно запрос  [new]
MathewSun
Member

Откуда: Москва
Сообщений: 17
aleks2
create index IDX_OrderEvents on OrderEvents ( Account, OrderId );

select top(1) 
	o.Id, 
	va.[Login], 
	o.OrderType
	from Orders o
        cross join 
        ( select top(1) va.[Login] 
            from Accounts va inner join Users u on u.UserId = va.UserId
            where va.IsActive = 1 and va.IsDeleted = 0 and u.UserName = @UserName 
        ) as X
	where 
	  o.IsDone = 0
	  and not exists ( select * from OrderEvents oe where va.[Login] = oe.Account and o.Id = oe.OrderId ) 
	order by va.LastActive, o.LastUpdate;


Запрос без индекса читает 12.000.
С индексом - всего 560 записей.

Спасибо!

Еще как-то оптимизировать возможно?
8 янв 16, 14:18    [18652384]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать и составить правильно запрос  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
@MathewSun планом выполнения поделитесь (*.sqlplan)?
8 янв 16, 15:34    [18652628]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить