powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Guid как id для многомилионной таблицы (тормоза)
25 сообщений из 31, страница 1 из 2
Guid как id для многомилионной таблицы (тормоза)
    #40054271
Фотография medoed
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день!
Есть такое архитектурное решение (изначально не моё):
1) Внешняя система заливает данные по проводкам в первичную таблицу как есть, при этом в виде guid каждой строки генерится рандомно и уникально набор символов, близкий по смыслу к GUID. По этому полю построен индекс (некластерный).
2) Есть уже реальная таблица в витрине с таким же именем и почти такой же структурой, которая синхронизируется с таблицей из пункта 1)

Сейчас возникают долгие запросы при синхронизации, этих 2-х таблиц. Так как кол-во строк порядка 30 мл-нов.

Вот думаю, в какую сторону копать. Вижу несколько вариантов:
а) Cделать это id поле числовым и заново попросить перелить таблицу1.
б) Генерить в поле id tableотсортированный гуид и накатить на него Primary Key кластерный - тогда запросы синхронизации , по типу

Код: sql
1.
 delete from table2 where not exists (select 1 from table1 where table1.id = table2.id)


пойдут побыстрее.
А как сделали бы вы , есть у вас такой опыт?
...
Рейтинг: 0 / 0
Guid как id для многомилионной таблицы (тормоза)
    #40054302
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
medoed
а) Cделать это id поле числовым и заново попросить перелить таблицу1.
б) Генерить в поле id tableотсортированный гуид и накатить на него Primary Key кластерный - тогда запросы синхронизации , по типу
а) разницы особой не будет. Хотя, конечно, инт всегда быстрее.
б) если синхронизация случайных записей, то разница будет только в отсутствии лукапа. Впрочем, какую то выгоду это даст.
...
Рейтинг: 0 / 0
Guid как id для многомилионной таблицы (тормоза)
    #40054361
Фотография SIMPLicity_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Посчитать хэш, но он, вероятно, итак считается.

GUID в качестве идентификатора взят, скорее всего, именно в расчёте на последующее сливание таблиц. Переход в INT заставит Вас потом рожать механизм синхронизации такой что бы избежать коллизий из серии "какого чёрта,- тут 12345678 и тут тоже 12345678, но они разные! ". Ну и вместо int брать стразу bigint ... В общем - посмотрите как выполняется запрос на слияние (возможно что у Вас запрос мудрёный, с доп.условиями) , и добавьте памяти и быстрый диск... 30 лямов записей - это не так уж и много...
...
Рейтинг: 0 / 0
Guid как id для многомилионной таблицы (тормоза)
    #40054389
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
medoed,

какой объём вставки одной транзакции?
...
Рейтинг: 0 / 0
Guid как id для многомилионной таблицы (тормоза)
    #40054403
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
medoed
Добрый день!
Есть такое архитектурное решение (изначально не моё):
1) Внешняя система заливает данные по проводкам в первичную таблицу как есть, при этом в виде guid каждой строки генерится рандомно и уникально набор символов, близкий по смыслу к GUID. По этому полю построен индекс (некластерный).
2) Есть уже реальная таблица в витрине с таким же именем и почти такой же структурой, которая синхронизируется с таблицей из пункта 1)

Сейчас возникают долгие запросы при синхронизации, этих 2-х таблиц. Так как кол-во строк порядка 30 мл-нов.

Вот думаю, в какую сторону копать. Вижу несколько вариантов:
а) Cделать это id поле числовым и заново попросить перелить таблицу1.
б) Генерить в поле id tableотсортированный гуид и накатить на него Primary Key кластерный - тогда запросы синхронизации , по типу

Код: sql
1.
 delete from table2 where not exists (select 1 from table1 where table1.id = table2.id)


пойдут побыстрее.
А как сделали бы вы , есть у вас такой опыт?


Сферическая синхронизация в вакууме?
И каким именно боком guid участвует в вашей "синхронизации"?
...
Рейтинг: 0 / 0
Guid как id для многомилионной таблицы (тормоза)
    #40054412
Фотография medoed
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
aleks222,
Покрасоваться решили? Запрос выше на примере delete ,в нем id типа guid.
...
Рейтинг: 0 / 0
Guid как id для многомилионной таблицы (тормоза)
    #40054413
Фотография medoed
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав Колосов,
С утра разовая вставка порядка 50 к записей. Ну и днём могут прилетать небольшие изменения(каждые 15 минут) по 100-500 записей.
...
Рейтинг: 0 / 0
Guid как id для многомилионной таблицы (тормоза)
    #40054414
Фотография medoed
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SIMPLicity_,
Не , слияние таблиц особо не предусмотрена. Тут клиенту просто привычней генерить символьный идентификатор для вставки в базу. Ну и классическая схема - быстрая вставка в табличку импорта, а дальше в самой базе уже через процедуру синхронизация с таблицей master. Синхронизация(полная, а не только свежих данных) , как раз через этот guid , так как он уникален. Ну и опасений нет, что числовой счётчик собъется.
Такая схема норм работала, пока не выросли объемы.
Оперативы достаточно и по процам норм. На ssd базу пока переносить не планируем
...
Рейтинг: 0 / 0
Guid как id для многомилионной таблицы (тормоза)
    #40054423
zeon11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
medoed,

Про логику синхронизации не пояснили, но судя по по приведённому Вами запросу с DELETE
в этой логике не всё оптимально. Т.е. по всей видимости сначала "набиваем под завязку" данными таблицу, а потом из таблицы "вычёркиваем" то, что не пригодилось.
Закономерно при таком подходе с ростом количества записей механизм будет проседать по производительности всё сильнее и сильнее, и замена GUID на любой другой идентификатор
только даст временную отсрочку.
Может быть есть возможность пересмотреть алгоритм синхронизации?
...
Рейтинг: 0 / 0
Guid как id для многомилионной таблицы (тормоза)
    #40054429
Фотография medoed
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
zeon11
medoed,

Про логику синхронизации не пояснили, но судя по по приведённому Вами запросу с DELETE
в этой логике не всё оптимально. Т.е. по всей видимости сначала "набиваем под завязку" данными таблицу, а потом из таблицы "вычёркиваем" то, что не пригодилось.
Закономерно при таком подходе с ростом количества записей механизм будет проседать по производительности всё сильнее и сильнее, и замена GUID на любой другой идентификатор
только даст временную отсрочку.
Может быть есть возможность пересмотреть алгоритм синхронизации?

Скорее вы правы. План и то что в нём не нравится прилагаю.

Переписать есть возможность - а как бы вы сделали? Во время вставки в первую таблицу , триггер на ней прикрутить, который будет данные синхронизировать во второй? Но мне кажется это тоже не самый гут вариант.
...
Рейтинг: 0 / 0
Guid как id для многомилионной таблицы (тормоза)
    #40054432
zeon11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
medoed,

Синхронизация двусторонняя? Т.е. новые данные появляются в двух таблицах, или нисходящая, т.е. новые данные появляются только в одной таблице?
...
Рейтинг: 0 / 0
Guid как id для многомилионной таблицы (тормоза)
    #40054434
Фотография medoed
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
zeon11
medoed,

Синхронизация двусторонняя? Т.е. новые данные появляются в двух таблицах, или нисходящая, т.е. новые данные появляются только в одной таблице?

Нисходящая только в таблице 1, потом они перетекают из неё в таблицу 2-ва.
...
Рейтинг: 0 / 0
Guid как id для многомилионной таблицы (тормоза)
    #40054436
zeon11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
medoed,

Можно сделать так, например, в обоих таблицах создать поле признака синхронизации.
Новые данные изначально помечаются признаком "Не синхронизированны". Затем при синхронизации признак переводится в состояние "Синхронизирован". Таким образом при первичной настройке серверу придётся "попотеть" на синхронизации, зато в последующем Вы получите ламинарный поток данных, без роста нагрузки во времени.
...
Рейтинг: 0 / 0
Guid как id для многомилионной таблицы (тормоза)
    #40054438
Фотография medoed
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
zeon11
medoed,

Можно сделать так, например, в обоих таблицах создать поле признака синхронизации.
Новые данные изначально помечаются признаком "Не синхронизированны". Затем при синхронизации признак переводится в состояние "Синхронизирован". Таким образом при первичной настройке серверу придётся "попотеть" на синхронизации, зато в последующем Вы получите ламинарный поток данных, без роста нагрузки во времени.

Но если находятся косяки, то часто бывает данные полностью переливаются в таблице 1 , тогда признак синхронизации не особо поможет. Так как источник синхронизации порядком изменился.
Прикрепляю план изначальный, который не нравится мне (таблицы тестовые)...
...
Рейтинг: 0 / 0
Guid как id для многомилионной таблицы (тормоза)
    #40054439
zeon11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В случае нисходящей синхронизации достаточно признак синхронизации поместить только в одну, рабочую таблицу. В накопительной таблице этот признак можно и не ставить.
И да, в рабочей таблице нужно сделать блокировку на изменение синхронизированных данных
(в триггере напр.)
...
Рейтинг: 0 / 0
Guid как id для многомилионной таблицы (тормоза)
    #40054441
zeon11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
medoed,

Извини, срочно уезжаю, вечером подумаю.
...
Рейтинг: 0 / 0
Guid как id для многомилионной таблицы (тормоза)
    #40054452
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
medoed
aleks222,
Покрасоваться решили? Запрос выше на примере delete ,в нем id типа guid.

В вашем запросе абсолютно фиолетово, что там целое или guid.
...
Рейтинг: 0 / 0
Guid как id для многомилионной таблицы (тормоза)
    #40054455
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
medoed
Прикрепляю план изначальный, который не нравится мне
Из эстетических соображений?

ЗЫ: Для синхронизации придумали инструкцию MERGE
...
Рейтинг: 0 / 0
Guid как id для многомилионной таблицы (тормоза)
    #40054459
Фотография medoed
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
aleks222
medoed
aleks222,
Покрасоваться решили? Запрос выше на примере delete ,в нем id типа guid.

В вашем запросе абсолютно фиолетово, что там целое или guid.

Однако int поменьше весит и по нему Primary Key кластерный можно построить!
Запрос будет в разы быстрее, нежели не по отсортированному GUID-у!
...
Рейтинг: 0 / 0
Guid как id для многомилионной таблицы (тормоза)
    #40054473
Фотография medoed
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm
medoed
Прикрепляю план изначальный, который не нравится мне
Из эстетических соображений?

ЗЫ: Для синхронизации придумали инструкцию MERGE

До этого с Db2 работал некоторое время - там Merge подглючивал.
Но вот переписал по вашему совету на Merge, та же самая хрень!
...
Рейтинг: 0 / 0
Guid как id для многомилионной таблицы (тормоза)
    #40054474
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
medoed
та же самая хрень!
Что именно является "хренью"? И что будет не "хренью"?
...
Рейтинг: 0 / 0
Guid как id для многомилионной таблицы (тормоза)
    #40054482
Фотография medoed
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm
medoed
та же самая хрень!
Что именно является "хренью"? И что будет не "хренью"?

Index Seek если весь запрос войдёт - будет гут!
...
Рейтинг: 0 / 0
Guid как id для многомилионной таблицы (тормоза)
    #40054483
.Евгений
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
medoed,

Подумайте над тем, что работать с полной копией (30 млн строк) данных по определению менее эффективно, чем с инкрементом (<= 50К строк).

Инкремент - это если бы вы удаляли из таблицы 1 данные, примененные на таблице 2 (в одной транзакции). Сложности с применением удалений к таблице 1 вполне решаемы (типично для ХД).

На худой конец приемлема имитация инкремента посредством признака синхронизации, о котором говорилось выше.
...
Рейтинг: 0 / 0
Guid как id для многомилионной таблицы (тормоза)
    #40054487
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
medoed
Index Seek если весь запрос войдёт - будет гут!
Вы, похоже, не понимаете как работают разные виды соединений.
Код: 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.
use tempdb;
set ansi_nulls, quoted_identifier, xact_abort on;
go

create table dbo.t1 (id int primary key);
create table dbo.t2 (id int primary key);

insert into dbo.t1
 (id)
output
 inserted.id into dbo.t2 (id)
 select top (1000000)
  row_number() over (order by 1/0)
 from
  master.dbo.spt_values a cross join
  master.dbo.spt_values b;
go

declare @c int;

set statistics xml, io, time on;
select @c = count(*) from dbo.t1 a where not exists(select 1 from dbo.t2 where id = a.id) option (maxdop 1, loop join);
select @c = count(*) from dbo.t1 a where not exists(select 1 from dbo.t2 where id = a.id) option (maxdop 1, merge join);
set statistics xml, io, time off;
go

drop table dbo.t1, dbo.t2;
go



Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
Table 't2'. Scan count 0, logical reads 3062509, physical reads 0, page server reads 0, read-ahead reads 14, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
Table 't1'. Scan count 1, logical reads 1615, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.

(1 row affected)

 SQL Server Execution Times:
   CPU time = 1266 ms,  elapsed time = 1290 ms.
Table 't2'. Scan count 1, logical reads 1615, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
Table 't1'. Scan count 1, logical reads 1615, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.

(1 row affected)

 SQL Server Execution Times:
   CPU time = 250 ms,  elapsed time = 300 ms.
...
Рейтинг: 0 / 0
Guid как id для многомилионной таблицы (тормоза)
    #40054492
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SIMPLicity_
Посчитать хэш, но он, вероятно, итак считается.

GUID в качестве идентификатора взят, скорее всего, именно в расчёте на последующее сливание таблиц. Переход в INT заставит Вас потом рожать механизм синхронизации такой что бы избежать коллизий из серии " какого чёрта,- тут 12345678 и тут тоже 12345678, но они разные! ". Ну и вместо int брать стразу bigint ... В общем - посмотрите как выполняется запрос на слияние (возможно что у Вас запрос мудрёный, с доп.условиями) , и добавьте памяти и быстрый диск... 30 лямов записей - это не так уж и много...


Так может думать совсем далекий девелопер, который не знаком со словом HASH
...
Рейтинг: 0 / 0
25 сообщений из 31, страница 1 из 2
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Guid как id для многомилионной таблицы (тормоза)
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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