Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Microsoft SQL Server |
![]() ![]() |
Winnipuh Member [заблокирован] Откуда: Київ Сообщений: 10428 |
Такой случай: есть главная таблица create table main ( id uniqueidentifier not null primary key, parent_id uniqueidentifier, name nvarchar(128), property1 int // ... ) есть подчиненная ей таблица с данными об изменении объекта create table main_changed ( id uniqueidentifier not null, changed_by_user int, changed_date datetime not null default (getdate()), ts timestamp ) Главная таблица содержит иерархию, во второй таблице записи апдейтятся для объектов при их изменении. Проблема в том, что часто возникают блокировки. Мне подкинули идею делать не апдейты, а только инсерты во вторую таблицу и выбирать только самые свежие записи по ts. Ключом похоже надо сделать во второй id+ts Вопрос: смогу ли я избежать блокировок в таком случае при одновременных инсертах от многих юзеров? Хотя бы по сравнению с версией с апдейтами |
24 ноя 12, 12:11 [13523173] Ответить | Цитировать Сообщить модератору |
Гавриленко Сергей Алексеевич Member Откуда: Moscow Сообщений: 37143 |
У вас какая-то странная таблица с историей. Зачем знать, что запись менялась, но не знать, что в ней было до изменения? |
24 ноя 12, 12:14 [13523181] Ответить | Цитировать Сообщить модератору |
Winnipuh Member [заблокирован] Откуда: Київ Сообщений: 10428 |
Вообще-то в файловой системе у файлов тоже есть дата изменения, но чаще нет предыдущего содержимого, чем есть. В чем-то вы правы, это отдельный вопрос... но для больших баз, если хранить еще и что изменилось, будет дурной размер базы. Там у главной есть подчиненные, где собственно хранятся специфические данные для объектов и т.д.. И хранить и сторию будет означать хранить данные из многих таблиц. Я упростил задачу по сравнению с реальной. Так что в данном случае важно хранить факт последнего изменения когда и кто. Вот и возник вопрос. |
||
24 ноя 12, 12:22 [13523190] Ответить | Цитировать Сообщить модератору |
aleks2
Guest |
Так историю переписывать легче. Это всеобщий подход. Даже в настоящей истории... |
||
24 ноя 12, 12:52 [13523224] Ответить | Цитировать Сообщить модератору |
Winnipuh Member [заблокирован] Откуда: Київ Сообщений: 10428 |
пока мне достаточно такой истории. Вопрос - при одновременной вставке не будет ли блокировок? Т.е. если индекс по гуиду и таймстампу |
24 ноя 12, 13:09 [13523247] Ответить | Цитировать Сообщить модератору |
Crimean Member Откуда: Сообщений: 13148 |
зависит от уровня изоляции, однако. но - да - можно сделать так, что не будет, если это не противоречит общей логики работы приложения (а то вдруг там блокировка "диапазонов" ключа для 100% контроля непересечения добавляемых записей - вот тогда никак) и заменяя update на insert вы, конечно, от блокировок частично убежите. да. но автоматом подымете требования на расчетную часть ибо посчитать "последнюю" запись - в целом недешево ибо агрегат прямо или косвенно (дада, можно top 1 order by, но смысл-то тот же). а вариант, когда последняя запись в истории, скажем, всегда имеет "номер = 0", а при добавлении новой - всем предыдущим делается "номер = номер + 1" и новая добавляется как "номер = 0", что убирает расчетную часть при вычитке "последней" - опять ведет к блокировкам. закон сохранения, увы, не обмануть |
||
24 ноя 12, 13:36 [13523310] Ответить | Цитировать Сообщить модератору |
Winnipuh Member [заблокирован] Откуда: Київ Сообщений: 10428 |
вот-вот, терзают смутные сомненья... Идея - в использовании таймстампа как части ключа. Т.е. гуид + таймстамп. Таймстамп всегда будет расти, а гуид, конечно зло еще то.. Вот нашел, народ пишет Inserts will just about always be quicker, especially if they are either in order or if the underlying table doesn't have a clustered index. |
||||
24 ноя 12, 13:39 [13523320] Ответить | Цитировать Сообщить модератору |
invm Member Откуда: Москва Сообщений: 9633 |
|
||
24 ноя 12, 14:10 [13523420] Ответить | Цитировать Сообщить модератору |
Crimean Member Откуда: Сообщений: 13148 |
invm, я подозреваю, там конкуренция за обновление / обновление, а не за чтение / обновление |
24 ноя 12, 14:29 [13523458] Ответить | Цитировать Сообщить модератору |
invm Member Откуда: Москва Сообщений: 9633 |
Crimean, Ну так если обновление/обновление, то есть и такая же конкуренция на базовой таблице и инсертом все равно ничего не решается. Вариант, что все делается вручную в автокоммите не рассматриваем. ![]() |
24 ноя 12, 15:28 [13523568] Ответить | Цитировать Сообщить модератору |
Гость333 Member Откуда: Сообщений: 3683 |
Winnipuh, На каких ресурсах возникают блокировки и какого вида? Какие индексы сейчас в таблице main_changed? (И вопрос не по теме — "id uniqueidentifier not null primary key" — этот индекс кластерный?) |
25 ноя 12, 12:47 [13525099] Ответить | Цитировать Сообщить модератору |
Winnipuh Member [заблокирован] Откуда: Київ Сообщений: 10428 |
Я в процессе переделок. Индекс я сделал там кластерный id+ts, чтобы быстро находить, ибо приходится брать самую свежу запись для данного ид. Ранее main была единственной таблицей, и хранит она иерархию. Так вот при изменении чилдренов надо изменить поле дата и юзер модификации. Триггеры делают это сейчас. Т.е. изменение в main в ней же срабатывают триггеры ищут парентов и меняют им дату и юзера. Жуть. По рекомендациям я пытаюсь развести таблицы, разнес, сталу лучше, меньше блокриовок, хотя количество чтений не уменьшилось, ясное дело - теперь приходистя скрещивать две таблицы при чтениях во многих местах. Такая фигня. Вот и подумал об инсертах. Стоит ли с ними заморачиваться. Т.е. сейчас отношение жостко 1=1, т.е присоздании главной записи создается подчиненная, и потом только апдейтится. А если сделать всегда только инсерты в main_changed, то хотелось бы понять: будет ли лучше для производительности? Вопрос роста к-ва записей пока не рассматирвается, хотя это станет проблемой. |
||
26 ноя 12, 13:08 [13528982] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47049 |
Winnipuh, а разве кластерный индекс по UNIQUEIDENTIFIER - это хорошо? Может, уже не будут в таблицу вставлять - тогда другое дело. |
26 ноя 12, 13:16 [13529045] Ответить | Цитировать Сообщить модератору |
Гость333 Member Откуда: Сообщений: 3683 |
Я так понял, кластерный по id+ts — это индекс по таблице main_changed (т.к. поле ts, согласно первому посту, есть только в ней). Значит, вставки будут идти постоянно, при каждом изменении main. Фрагментация индекса будет печальная совсем :) |
||
26 ноя 12, 13:30 [13529161] Ответить | Цитировать Сообщить модератору |
Все форумы / Microsoft SQL Server | ![]() |