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

Откуда:
Сообщений: 2231
Собственно вопрос вот в чем: где бы почитать (дайте тынц) или расскажите "на пальцах", используются ли индексы в таблицах Inserted/Deleted и какова логика сервера при построении индексов на эти служебные таблички?
26 авг 14, 09:50    [16492128]     Ответить | Цитировать Сообщить модератору
 Re: Индексы в Inserted/Deleted  [new]
invm
Member

Откуда: Москва
Сообщений: 9413
PaulWist
используются ли индексы в таблицах Inserted/Deleted
Нет.
26 авг 14, 10:10    [16492212]     Ответить | Цитировать Сообщить модератору
 Re: Индексы в Inserted/Deleted  [new]
PaulWist
Member

Откуда:
Сообщений: 2231
invm
PaulWist
используются ли индексы в таблицах Inserted/Deleted
Нет.


1. Ок, спасибо.

2. Тогда синтаксис триггера в варианте (2) будет правилен (в смысле производительности):

create table t (id int primary key, f1 char(10))
go

create index idx_t on t (f1)
go

create trigger tr_t on t
AFTER INSERT, UPDATE, DELETE
AS 
if exists  
(select 1 from Inserted I
inner join t on I.ID = t.ID
-- (1) -- фильтровать по служебной таблице
where I.f1 between 'AA' and 'BB'
-- или (2) -- фильтровать по целевой таблице
-- where t.f1 between 'AA' and 'BB')
26 авг 14, 10:40    [16492368]     Ответить | Цитировать Сообщить модератору
 Re: Индексы в Inserted/Deleted  [new]
iap
Member

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

для INSERT и UPDATE триггер AFTER INSERT,UPDATE вызовется после выполнения этих команд,
так что inserted JOIN t не имеет смысла, ибо inserted - это часть самой таблицы после её изменения.
Однако, inserted не содержит ни одной записи, если был выполнен DELETE.
Для этого случая у Вас в триггере не предусмотрено НИЧЕГО
26 авг 14, 10:59    [16492465]     Ответить | Цитировать Сообщить модератору
 Re: Индексы в Inserted/Deleted  [new]
PaulWist
Member

Откуда:
Сообщений: 2231
iap
Однако, inserted не содержит ни одной записи, если был выполнен DELETE.
Для этого случая у Вас в триггере не предусмотрено НИЧЕГО


Да-да, конечно :) спасибо за напоминание.

AFTER INSERT, UPDATE, DELETE


был скопирован из шаблона триггера (лень было руками колотить).

iap

для INSERT и UPDATE триггер AFTER INSERT,UPDATE вызовется после выполнения этих команд,
так что inserted JOIN t не имеет смысла, ибо inserted - это часть самой таблицы после её изменения.


Не понял, если не join-ить табличку Inserted c исходной t, то как узнать в триггере ТОЛЬКО по таблице t какие записи поменялись/добавились?
26 авг 14, 11:10    [16492548]     Ответить | Цитировать Сообщить модератору
 Re: Индексы в Inserted/Deleted  [new]
invm
Member

Откуда: Москва
Сообщений: 9413
PaulWist
как узнать в триггере ТОЛЬКО по таблице t какие записи поменялись/добавились?
Поменявшиеся/добавившиеся записи находятся в inserted. Зачем для этого лезть в t?
26 авг 14, 11:24    [16492647]     Ответить | Цитировать Сообщить модератору
 Re: Индексы в Inserted/Deleted  [new]
baracs
Member

Откуда: Москва
Сообщений: 7204
PaulWist
Не понял, если не join-ить табличку Inserted c исходной t, то как узнать в триггере ТОЛЬКО по таблице t какие записи поменялись/добавились?
Использование таблиц inserted и deleted.
26 авг 14, 11:25    [16492659]     Ответить | Цитировать Сообщить модератору
 Re: Индексы в Inserted/Deleted  [new]
sphinx_mv
Member [заблокирован]

Откуда:
Сообщений: 1672
[quot PaulWist]
iap
Не понял, если не join-ить табличку Inserted c исходной t, то как узнать в триггере ТОЛЬКО по таблице t какие записи поменялись/добавились?
Внешнее объединение inserted и deleted
26 авг 14, 11:26    [16492668]     Ответить | Цитировать Сообщить модератору
 Re: Индексы в Inserted/Deleted  [new]
PaulWist
Member

Откуда:
Сообщений: 2231
invm
PaulWist
как узнать в триггере ТОЛЬКО по таблице t какие записи поменялись/добавились?
Поменявшиеся/добавившиеся записи находятся в inserted. Зачем для этого лезть в t?


Повторюсь.
create trigger tr_t on t
AFTER INSERT, UPDATE, DELETE
AS 
if exists  
(select 1 from Inserted I
inner join t on I.ID = t.ID
-- (1) -- фильтровать по служебной таблице
where I.f1 between 'AA' and 'BB'
-- или (2) -- фильтровать по целевой таблице
-- where t.f1 between 'AA' and 'BB')


Триггер использует обьединение по первичному ключу и фильтр по вспомогательному полю

where f1 between 'AA' and 'BB'


собственно вопрос в том, как правильно написать секцию where, те фильтровать по Inserted или по исходной табле t.
26 авг 14, 11:49    [16492877]     Ответить | Цитировать Сообщить модератору
 Re: Индексы в Inserted/Deleted  [new]
PaulWist
Member

Откуда:
Сообщений: 2231
2 baracs, sphinx_mv

Вы, наверное, невнимательно прочли вопрос:

автор
как узнать в триггере ТОЛЬКО по таблице t какие записи поменялись/добавились?
26 авг 14, 11:51    [16492894]     Ответить | Цитировать Сообщить модератору
 Re: Индексы в Inserted/Deleted  [new]
Glory
Member

Откуда:
Сообщений: 104760
PaulWist
собственно вопрос в том, как правильно написать секцию where, те фильтровать по Inserted или по исходной табле t.

А что у таблицы t есть какие то дополнительные индексы ?
26 авг 14, 11:52    [16492902]     Ответить | Цитировать Сообщить модератору
 Re: Индексы в Inserted/Deleted  [new]
invm
Member

Откуда: Москва
Сообщений: 9413
PaulWist
собственно вопрос в том, как правильно написать секцию where
create trigger tr_t on t
AFTER INSERT, UPDATE, DELETE
AS
... 
if exists (select 1 from Inserted I where I.f1 between 'AA' and 'BB')
...
26 авг 14, 11:53    [16492907]     Ответить | Цитировать Сообщить модератору
 Re: Индексы в Inserted/Deleted  [new]
PaulWist
Member

Откуда:
Сообщений: 2231
Glory
PaulWist
собственно вопрос в том, как правильно написать секцию where, те фильтровать по Inserted или по исходной табле t.

А что у таблицы t есть какие то дополнительные индексы ?


Не понял, про какие доп. индексы вы говорите, поясните?

Скрипт приведён выше https://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=1112580&msg=16492368

create table t (id int primary key, f1 char(10))
go

create index idx_t on t (f1)
go

create trigger tr_t on t
AFTER INSERT, UPDATE, DELETE
AS 
if exists  
(select 1 from Inserted I
inner join t on I.ID = t.ID
-- (1) -- фильтровать по служебной таблице
where I.f1 between 'AA' and 'BB'
-- или (2) -- фильтровать по целевой таблице
-- where t.f1 between 'AA' and 'BB')
26 авг 14, 11:58    [16492947]     Ответить | Цитировать Сообщить модератору
 Re: Индексы в Inserted/Deleted  [new]
Glory
Member

Откуда:
Сообщений: 104760
PaulWist
Не понял, про какие доп. индексы вы говорите, поясните?

В чем тогшда смысл соединения inserted с базовой таблицей, если в inserted есть уже все, что надо для проверки ?
26 авг 14, 12:00    [16492963]     Ответить | Цитировать Сообщить модератору
 Re: Индексы в Inserted/Deleted  [new]
PaulWist
Member

Откуда:
Сообщений: 2231
invm
PaulWist
собственно вопрос в том, как правильно написать секцию where
create trigger tr_t on t
AFTER INSERT, UPDATE, DELETE
AS
... 
if exists (select 1 from Inserted I where I.f1 between 'AA' and 'BB')
...


Ага, те получается, что "дешевле" использовать скан по виртуальной таблице, чем обьединение виртуальной с исходной по первичному ключу и фильтрация по доп. индексированному параметру в исходной табличке, я правильно понял?
26 авг 14, 12:06    [16493014]     Ответить | Цитировать Сообщить модератору
 Re: Индексы в Inserted/Deleted  [new]
Glory
Member

Откуда:
Сообщений: 104760
PaulWist
Ага, те получается, что "дешевле" использовать скан по виртуальной таблице, чем обьединение виртуальной с исходной по первичному ключу и фильтрация по доп. индексированному параметру в исходной табличке, я правильно понял?

Для ответов на такие вопросы смотрят в план выполнения.
Также план покажет что сканируется, а что нет.
26 авг 14, 12:08    [16493032]     Ответить | Цитировать Сообщить модератору
 Re: Индексы в Inserted/Deleted  [new]
PaulWist
Member

Откуда:
Сообщений: 2231
Glory
PaulWist
Не понял, про какие доп. индексы вы говорите, поясните?

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


Моё понимание такое, что для поиска во Insrerted сервер должен просканировать всю вирт. таблицу, в то время если провести обьединение Inserted с исходной табличкой, то сервер, наверное, может использовать индекс по полю фильтрации t.f1.
26 авг 14, 12:18    [16493107]     Ответить | Цитировать Сообщить модератору
 Re: Индексы в Inserted/Deleted  [new]
Glory
Member

Откуда:
Сообщений: 104760
PaulWist
Моё понимание такое,

Вы окончили курсы оптимизаторов ?
26 авг 14, 12:21    [16493124]     Ответить | Цитировать Сообщить модератору
 Re: Индексы в Inserted/Deleted  [new]
HoBTID
Member

Откуда:
Сообщений: 929
PaulWist
Моё понимание такое, что для поиска во Insrerted сервер должен просканировать всю вирт. таблицу,
в то время если провести обьединение Inserted с исходной табличкой, то сервер, наверное,
может использовать индекс по полю фильтрации t.f1.
Как это ни смешно, у Вас почти правильное понимание.

Маленький нюанс заключается в том, что виртуальная таблица insrerted содержит не все записи основной,
а только те, которые были изменены командой вызвавшей триггер (последним INSERT'ом, например).
Т.е. содержит очень МАЛО записей.
И скорее всего, они все эти записи так и остались в памяти, значит к диску обращаться не придется.

Поэтому, обращение в триггере к вирт. таблицам inserted и deleted гораздо эффективнее, чем к основной таблице.
26 авг 14, 14:06    [16493977]     Ответить | Цитировать Сообщить модератору
 Re: Индексы в Inserted/Deleted  [new]
iap
Member

Откуда: Москва
Сообщений: 47001
HoBTID
PaulWist
Моё понимание такое, что для поиска во Insrerted сервер должен просканировать всю вирт. таблицу,
в то время если провести обьединение Inserted с исходной табличкой, то сервер, наверное,
может использовать индекс по полю фильтрации t.f1.
Как это ни смешно, у Вас почти правильное понимание.

Маленький нюанс заключается в том, что виртуальная таблица insrerted содержит не все записи основной,
а только те, которые были изменены командой вызвавшей триггер (последним INSERT'ом, например).
Т.е. содержит очень МАЛО записей.
И скорее всего, они все эти записи так и остались в памяти, значит к диску обращаться не придется.

Поэтому, обращение в триггере к вирт. таблицам inserted и deleted гораздо эффективнее, чем к основной таблице.
Упускаете, что для JOINа всё равно придётся обращаться ко всей inserted,
но сверх этого ещё и подбирать соответствующие записи в таблице.
Вот это второе действие - лишнее и требует ненулевых затрат.
Разве это не очевидно?
26 авг 14, 14:19    [16494089]     Ответить | Цитировать Сообщить модератору
 Re: Индексы в Inserted/Deleted  [new]
HoBTID
Member

Откуда:
Сообщений: 929
iap
Упускаете, что для JOINа всё равно придётся обращаться ко всей inserted,
но сверх этого ещё и подбирать соответствующие записи в таблице.
Вот это второе действие - лишнее и требует ненулевых затрат.
Разве это не очевидно?

Зачем автору джоин - совершенно непонятно.
Может он просто не знает, как без джоина сделать?

PaulWist, Ваш фильтрует только те записи, которые есть в основной таблице
и были только что вставлены или обновлены.

НО таблица inserted и так содержит только те записи,
которые были вставлены или обновлены.
Там нет удаленных записей!
(Если только у Вас еще один триггер их не удаляет после этого триггера).

Попробуйте сделать вот так:

CREATE TRIGGER tr_t ON t
AFTER INSERT, UPDATE, DELETE
AS 
IF EXISTS  
(SELECT 1 FROM inserted AS ins
WHERE ins.f1 BETWEEN 'AA' AND 'BB')
26 авг 14, 16:07    [16495028]     Ответить | Цитировать Сообщить модератору
 Re: Индексы в Inserted/Deleted  [new]
sphinx_mv
Member [заблокирован]

Откуда:
Сообщений: 1672
PaulWist
2 baracs, sphinx_mv

Вы, наверное, невнимательно прочли вопрос:

автор
как узнать в триггере ТОЛЬКО по таблице t какие записи поменялись/добавились?
"Вам нужны шашечки или Вам надо ехать?" (с) анек
26 авг 14, 17:19    [16495625]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить