powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Clustered index scan родительской таблицы, при добавлении записей в дочернюю
25 сообщений из 29, страница 1 из 2
Clustered index scan родительской таблицы, при добавлении записей в дочернюю
    #39609097
ДонАтелло
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не могу сообразить как можно отвадить SQL сканировать родительскую таблицу, при добавлении записей в дочернюю.
Особенно, учитывая тот факт, что значение в foreign key поле заносится из константы, т.е. там заведомо одно единственное значение. Вот в таком виде (при добавлении одной записи) в плане видим seek. Но стоит увеличить число записей (раскомментировать top и from), то на моём сервере уже при 39 записях SQL меняет seek на scan.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
/*
create table dbo.Table_Master
(
	ID			int	identity(1,1)	not null	constraint PK_Table_Master primary key
	,Place_Holder	varchar(10)		not null
)

create table dbo.Table_Detail
(
	ID			int	identity(1,1)	not null	constraint PK_Table_Detail primary key
	,Master_ID		int				not null	constraint FK_Table_Detail__Table_Master foreign key references dbo.Table_Master (ID)
	,Place_Holder	varchar(10)		not null
)
*/

declare @ID int

insert into dbo.Table_Master
	(Place_Holder)
select
	'aaaa' as Place_Holder

set @ID = @@identity

insert into dbo.Table_Detail
	(Master_ID, Place_Holder)
select-- top 39
	@ID as Master_ID
	,'bbbbb' as Place_Holder
--from sys.tables



Forceseek для insert не разрешает Майкрософт.
...
Рейтинг: 0 / 0
Clustered index scan родительской таблицы, при добавлении записей в дочернюю
    #39609101
ДонАтелло
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Имеется в виду второй запрос в плане (рис.)
...
Рейтинг: 0 / 0
Clustered index scan родительской таблицы, при добавлении записей в дочернюю
    #39609117
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДонАтелло,

ну всавьте миллион записей в Table_Master :)
...
Рейтинг: 0 / 0
Clustered index scan родительской таблицы, при добавлении записей в дочернюю
    #39609154
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДонАтелло,

Вам доподлинно известно, что NL будет выгоднее MERGE или HASH?
...
Рейтинг: 0 / 0
Clustered index scan родительской таблицы, при добавлении записей в дочернюю
    #39609204
ДонАтелло
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TaPaKДонАтелло,

ну всавьте миллион записей в Table_Master :)

:)
В данном случае таблица, как раз, маленькая. Автоочищаемая со временем... Но да, можно залить бетону для прочности... Как вариант...
...
Рейтинг: 0 / 0
Clustered index scan родительской таблицы, при добавлении записей в дочернюю
    #39609207
ДонАтелло
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invmДонАтелло,

Вам доподлинно известно, что NL будет выгоднее MERGE или HASH?

А при чём тут это? Это join вкорячивает сам SQL на основании наличия foreign key. Вопрос, как раз, и состоит в том, знает ли кто-либо способ повлиять на этот join?
...
Рейтинг: 0 / 0
Clustered index scan родительской таблицы, при добавлении записей в дочернюю
    #39609215
ДонАтелло,

в каждой таблица строк по сколько? примерно по 39?
...
Рейтинг: 0 / 0
Clustered index scan родительской таблицы, при добавлении записей в дочернюю
    #39609221
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДонАтеллоА при чём тут это? Это join вкорячивает сам SQL на основании наличия foreign key. Вопрос, как раз, и состоит в том, знает ли кто-либо способ повлиять на этот join?Если вас не устраивает "вкоряченное" - избавьтесь от FK.
Если же считаете, что лучше сервера знаете как соединить таблицы, то добавьте к запросу option (loop join) и будет вам счастье в виде Nested Loops + Index Seek.
...
Рейтинг: 0 / 0
Clustered index scan родительской таблицы, при добавлении записей в дочернюю
    #39609269
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДонАтеллоTaPaKДонАтелло,

ну всавьте миллион записей в Table_Master :)

:)
В данном случае таблица, как раз, маленькая. Автоочищаемая со временем... Но да, можно залить бетону для прочности... Как вариант...
мда... если вставити 1кк то получите seek. Я так понимаю вы боитесь слова "scan"
...
Рейтинг: 0 / 0
Clustered index scan родительской таблицы, при добавлении записей в дочернюю
    #39609282
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДонАтеллоinvmДонАтелло,

Вам доподлинно известно, что NL будет выгоднее MERGE или HASH?

А при чём тут это? Это join вкорячивает сам SQL на основании наличия foreign key. Вопрос, как раз, и состоит в том, знает ли кто-либо способ повлиять на этот join?Как же сервер может сделать проверку на существование записи, не вкорячивая join? Сказали проверять, он и проверяет.
...
Рейтинг: 0 / 0
Clustered index scan родительской таблицы, при добавлении записей в дочернюю
    #39609329
ДонАтелло
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invmДонАтеллоА при чём тут это? Это join вкорячивает сам SQL на основании наличия foreign key. Вопрос, как раз, и состоит в том, знает ли кто-либо способ повлиять на этот join?Если вас не устраивает "вкоряченное" - избавьтесь от FK.
Если же считаете, что лучше сервера знаете как соединить таблицы, то добавьте к запросу option (loop join) и будет вам счастье в виде Nested Loops + Index Seek.

Блин... Отчего-то был уверен что insert проигнорирует option. Виноват. В таком виде - да, пошёл seek на любых кол-вах...
От FK избавляться не очень хочется.
Но, т.к. вставляются записи ВСЕГДА строго по одному мастеру, то я считаю этот вариант тут вполне приемлемым.
Спасибо.
...
Рейтинг: 0 / 0
Clustered index scan родительской таблицы, при добавлении записей в дочернюю
    #39609330
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Основательный человек, сам старательно раскладывает грабли
...
Рейтинг: 0 / 0
Clustered index scan родительской таблицы, при добавлении записей в дочернюю
    #39609343
ДонАтелло
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TaPaK,

Я не боюсь слова scan. Мне немного не нравятся дедлоки, вероятность которых, при наличии сканов резко возрастает. А так-то я более чем толерантен.
...
Рейтинг: 0 / 0
Clustered index scan родительской таблицы, при добавлении записей в дочернюю
    #39609348
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДонАтеллоМне немного не нравятся дедлоки, вероятность которых, при наличии сканов резко возрастает.При наличии сканов таблиц из одной записи? Вряд ли возрастает.
...
Рейтинг: 0 / 0
Clustered index scan родительской таблицы, при добавлении записей в дочернюю
    #39609354
ДонАтелло
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alexeyvg,

Кто сказал что одной? Это вставляю я N записей в Detail с гаранитрованно одним Master_ID. Но из этого никак не следует что в мастере нет к этому времени других записей.
И в профилировщике я чётко видел блокировки накладываемые этим сканом на посторонние (ну относительно текущего контекста)записи.
Как минимум на одну постороннюю запись. Ту, детали которой сейчас вставляет вторая, конкурирующая сессия.
...
Рейтинг: 0 / 0
Clustered index scan родительской таблицы, при добавлении записей в дочернюю
    #39609375
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДонАтеллоМне немного не нравятся дедлоки, вероятность которых, при наличии сканов резко возрастает.Возникновение дедлоков не зависит от метода доступа, а зависит от порядка наложения блокировок на ресурсы, к которым идет конкурентное обращение.
...
Рейтинг: 0 / 0
Clustered index scan родительской таблицы, при добавлении записей в дочернюю
    #39609380
ДонАтелло
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm,

Да, но не только. Сканы в MSDN не указаны, как основная причина (тут не причины, а меры по предотвращению, но не суть, Ваша - первая):

•Access objects in the same order.
•Avoid user interaction in transactions.
•Keep transactions short and in one batch.
•Use a lower isolation level.
•Use a row versioning-based isolation level.
◦Set READ_COMMITTED_SNAPSHOT database option ON to enable read-committed transactions to use row versioning.
◦Use snapshot isolation.
•Use bound connections.

Но в массе литературы (у того же Короткевича) раздел посвящённый борьбе с взаимоблокировками начинается с фразы:
"...They can happen due to the scans introduced by non-optimized queries."
И трудно с ним не согласится... Если транзакция, которая собирается вставлять детали мастера 1, пусть, даже, кратковременно блокирует все записи в таблице мастер, то когда она поссорится с другой сессией, которая вставляет детали мастера 2 и тоже будет блокировать все записи в таблице мастер - это вопрос времени.
На приведённом тут примере это показать проще простого, если интересно.
...
Рейтинг: 0 / 0
Clustered index scan родительской таблицы, при добавлении записей в дочернюю
    #39609400
Сканы в MSDN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ДонАтелло,

автор•Access objects in the same order.
•Keep transactions short and in one batch.

Вот оно и есть. "Скан" сам по себе еще ничего не означает.
Но он лочит очень много всего, в т.ч. лишнего (п3) и в слабопредсказуемом порядке (п1)
...
Рейтинг: 0 / 0
Clustered index scan родительской таблицы, при добавлении записей в дочернюю
    #39609406
ДонАтелло
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сканы в MSDN,

Да, ну и я о том же... Мораль то всё равно одна... Избегать их надо, по возможности.
...
Рейтинг: 0 / 0
Clustered index scan родительской таблицы, при добавлении записей в дочернюю
    #39609410
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И что же будет лочить скан на read committed?
...
Рейтинг: 0 / 0
Clustered index scan родительской таблицы, при добавлении записей в дочернюю
    #39609412
ДонАтелло
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm,

Я же не писал "всегда" или "везде"... Я написал что не надо лопатить больше чем надо, когда это не надо. Если Вас задело использование термина scan для обозначения "лишнего" - искренне прошу прощения.

Вопрос решён. Спасибо за помощь. Лично Вам. И лично Вам же "извините" за то что не сразу понял Ваше
invmДонАтелло,

Вам доподлинно известно, что NL будет выгоднее MERGE или HASH?

как направление мысли, а не как вопрос не по теме.

Но Вы же не хотите "прямо сейчас открыть дискуссию" © об уровнях блокировок?
[spoiler][youtube=
YouTube Video
...
Рейтинг: 0 / 0
Clustered index scan родительской таблицы, при добавлении записей в дочернюю
    #39609429
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДонАтеллоЯ написал что не надо лопатить больше чем надо, когда это не надо.В вашем примере именно по этой причине оптимизатор ушел от NL к MERGE.
...
Рейтинг: 0 / 0
Clustered index scan родительской таблицы, при добавлении записей в дочернюю
    #39609466
ДонАтелло
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm,

Ну, видимо, Вы имеете в виду, что MERGE, особенно по кластерному ключу, который уже отсортирован - это наискорейший вариант соединения двух наборов данных.
Однако, памятуя, что при read committed движок будет последовательно блокировать (и тут же отпускать) каждую запись из мастера, мы получаем, что даже в самом лучшем сценарии, когда все сканы производятся по порядку, мы наталкиваемся на блокировку второй сессии, которая будет ждать первую, несмотря на то, что они наполняют два разных Table_Master.ID деталями.
Т.е. мы выстроим запросы в очередь, чего, явно, не требуется.
В моём случае ситуация чуть сложнее. Таблиц с детализацией 5 штук. Т.е. запрос выглядит, условно, так:
begin tran
insert 1 row into Master
insert into it's Detail1
insert into it's Detail2
insert into it's Detail3
insert into it's Detail4
insert into it's Detail5
commit tran

Несложно увидеть, что тут будет 5 полных сканов мастера. Беря во внимание параллельные сессии, которые делают то же самое, +возможное нарушение порядка сканирования кластерного ключа мастера в следствии каких-нибудь merry-go-round scans, получаем вероятность взаимоблокировки. На ровном, в общем-то, месте.
На рисунке видно, что вторая сессия, в некий момент, напарывается на блокировку первой сессии. Хотя вторая сессия добавляет детали к совсем другой записи, нежели первая.
...
Рейтинг: 0 / 0
Clustered index scan родительской таблицы, при добавлении записей в дочернюю
    #39609479
aleksrov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
begin tran
insert 1 row into Master
insert into it's Detail1
insert into it's Detail2
insert into it's Detail3
insert into it's Detail4
insert into it's Detail5
commit tran
Шикарно, в одной транзакци.
А так да, блакировки на ровном месте.
...
Рейтинг: 0 / 0
Clustered index scan родительской таблицы, при добавлении записей в дочернюю
    #39609522
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДонАтеллоНа рисунке видно, что вторая сессия, в некий момент, напарывается на блокировку первой сессии. Хотя вторая сессия добавляет детали к совсем другой записи, нежели первая.Это блокировка, а не взаимоблокировка.
Рассматривая только ваш случай, конкуренция может привести к взаимоблокировке, если будет allocation order scan.
...
Рейтинг: 0 / 0
25 сообщений из 29, страница 1 из 2
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Clustered index scan родительской таблицы, при добавлении записей в дочернюю
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]