|
блокировки при удалении покрывающего индекса
|
|||
---|---|---|---|
#18+
привет, подскажите пожалуйста что можно сделать в такой ситуации: есть таблица А которая имеет примерно 3 млн записей, и которая часто используется пользователями в запросах select (высоко нагруженная) Есть отдельная база данных с такой же таблицей/ В этой базе собираются данные и записываются в аналогичную таблицу. Затем джоб копирует данные из этой таблицы в рабочую и тут возникают проблемы с блокировками. На текущий момент я реализовал так Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
Ранее на AutoSupply.dbo.t_МагазинПоТоварам был ключ по Магазин и Товар, но возникали блокировки когда я удалял ключ перед копированием данных. То есть в момент Код: sql 1.
возникали блокировки Затем я попробовал сделать вместо ключа покрывающий некластеризованный индекс, думал удаление такого индекса не дает блокировок, но я ошибся Код: sql 1.
в общем сейчас решил создать уникальный некласт индекс на поля Магазин и Товар и не удалять его перед и создавать после Таблица обновляет каждые 15 минут, при этом в момент обновления запрещается создание документов, поэтому само обновление (копирование данных) должно производиться максимально быстро. Может кто сталкивался с этим и может помочь советом как лучше поступить спасибо ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2020, 09:54 |
|
блокировки при удалении покрывающего индекса
|
|||
---|---|---|---|
#18+
1. почему не truncate, если все равно удаляются все записи? 2. любое изменение схемы объекта, как например удаление индекса, всегда даст Sch-M. 3. если дропать кластерный (PK видимо был кластерный), то таблица из кластерного состояния перестраивается в кучу, это будет дольше, чем просто дропнуть некластерный. 4. верните уже свой кластерный на место, и в соседней базе, раз там *аналогичная* таблица, сделайте такой же кластерный. а при инсерте делайте не просто селект, а упорядоченный с order by по ключу кластерного (order by Магазин, Товар). все ваше время убивалось не на инсерт, а на сортировку для вставки в любой индекс 5. если простая модель, то еще лучше вставить с таблоком. моментально выйдет, 3 млн это не объем ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2020, 10:40 |
|
блокировки при удалении покрывающего индекса
|
|||
---|---|---|---|
#18+
Yasha123, спасибо большое за ответ 1. truncate не использую потому что он тоже блокирует данные (насколько я понял) 2. реализовал вставку по твоему совету Код: sql 1. 2. 3. 4.
на таблице источнике добавил аналогичный ключ. Процесс копирования занимает 18 секунд - это нормально? то есть примерно на 8 секунд медленнее чем скопировать и затем восстановить покрывающий некластерный индекс. Может я что-то упустил? ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2020, 11:15 |
|
блокировки при удалении покрывающего индекса
|
|||
---|---|---|---|
#18+
Sandist 1. truncate не использую потому что он тоже блокирует данные (насколько я понял) Sandist Процесс копирования занимает 18 секунд - это нормально? то есть примерно на 8 секунд медленнее чем скопировать и затем восстановить покрывающий некластерный индекс. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2020, 11:23 |
|
блокировки при удалении покрывающего индекса
|
|||
---|---|---|---|
#18+
alexeyvg, ребята, подскажите пожалуйста из своего опыта как скопировать данные без создания блокировок (обязательно и truncate не подходит) и при этом максимально быстро зная, что таблица высоко нагружена и там нужен индекс на Магазин+Товар ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2020, 11:32 |
|
блокировки при удалении покрывающего индекса
|
|||
---|---|---|---|
#18+
Sandist примерно на 8 секунд медленнее чем скопировать и затем восстановить покрывающий некластерный индекс. Может я что-то упустил? что-то ключи кластерного внезапно поменялись. план покажите(актуальный), что-то есть сомнения по структурам таблицы-источника и таблицы-приемника. вставить в пустой кластерный из отсортированного уже источника будет быстрее, чем сперва вставить, а потом с нуля сортировать ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2020, 12:41 |
|
блокировки при удалении покрывающего индекса
|
|||
---|---|---|---|
#18+
Sandist как скопировать данные без создания блокировок (обязательно и truncate не подходит) и при этом максимально быстро зная, что таблица высоко нагружена и там нужен индекс на Магазин+Товар копировать не в эту таблицу, а в аналогичную стэйджинговую, по завершении копирования транкейтить таблицу-приемник и сделать на нее switch стэйджинговой авторtruncate не использую потому что он тоже блокирует данные (насколько я понял) и что? truncate это 0 секунд. truncate + switch тоже 0 секунд. но лучше конечно делитить и писать построчно в лог, delete-то у нас ничего не блокирует, правда? ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2020, 12:48 |
|
блокировки при удалении покрывающего индекса
|
|||
---|---|---|---|
#18+
Sandist Может кто сталкивался с этим и может помочь советом как лучше поступить Ну коль пошла такая пЪянка - режЪ последний огурец. 1. Добавлям в AutoSupply.dbo.t_МагазинПоТоварам поле version, записываем туды 1. Делаем кластерный индекс (version, Магазин, Товар). 2. Переименовываем таблицу AutoSupply.dbo.t_МагазинПоТоварам_Hidden. 3. Делаем вьюху AutoSupply.dbo.t_МагазинПоТоварам as select * from AutoSupply.dbo.t_МагазинПоТоварам_Hidden where version = 1. 4. Все радостно работают. 5. Копируем новые записи insert into AutoSupply.dbo.t_МагазинПоТоварам(version, Магазин, Товар, и куча полей) select 2, Магазин, Товар, и куча полей from dbo.t_МагазинПоТоварам with(nolock) 6. Alter View AutoSupply.dbo.t_МагазинПоТоварам as select * from AutoSupply.dbo.t_МагазинПоТоварам_Hidden where version = 2 7. Это дело 1 сек. Никто и не заметит. Все радостно работают. 8. И у тя 15 мин на удаление delete from AutoSupply.dbo.t_МагазинПоТоварам_Hidden where version = 1. Если удалять пачками по 5000 - таблица будет НЕзаблокирована. 9. Повторяем с п5. Пока не надоест. ЗЫ. Канешно, swith круче. ЗЗЫ. Кстати Alter View необязателен. Можно вспомогательной табличкой откосить. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2020, 13:09 |
|
блокировки при удалении покрывающего индекса
|
|||
---|---|---|---|
#18+
Yasha123 Sandist как скопировать данные без создания блокировок (обязательно и truncate не подходит) и при этом максимально быстро зная, что таблица высоко нагружена и там нужен индекс на Магазин+Товар копировать не в эту таблицу, а в аналогичную стэйджинговую, по завершении копирования транкейтить таблицу-приемник и сделать на нее switch стэйджинговой авторtruncate не использую потому что он тоже блокирует данные (насколько я понял) и что? truncate это 0 секунд. truncate + switch тоже 0 секунд. но лучше конечно делитить и писать построчно в лог, delete-то у нас ничего не блокирует, правда? Извините, вопрос : что подразумевается под " switch " ? PS Это что-то новое? Или способ реализации чего-либо? Где почитать? Заранее спасибо! ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2020, 13:54 |
|
блокировки при удалении покрывающего индекса
|
|||
---|---|---|---|
#18+
SIMPLicity_ Yasha123 пропущено... копировать не в эту таблицу, а в аналогичную стэйджинговую, по завершении копирования транкейтить таблицу-приемник и сделать на нее switch стэйджинговой пропущено... и что? truncate это 0 секунд. truncate + switch тоже 0 секунд. но лучше конечно делитить и писать построчно в лог, delete-то у нас ничего не блокирует, правда? Извините, вопрос : что подразумевается под " switch " ? PS Это что-то новое? Или способ реализации чего-либо? Где почитать? Заранее спасибо! https://www.cathrinewilhelmsen.net/2015/04/19/table-partitioning-in-sql-server-partition-switching/ https://docs.microsoft.com/ru-ru/sql/t-sql/statements/alter-table-transact-sql?view=sql-server-ver15 ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2020, 14:02 |
|
блокировки при удалении покрывающего индекса
|
|||
---|---|---|---|
#18+
felix_ff SIMPLicity_ пропущено... Извините, вопрос : что подразумевается под " switch " ? PS Это что-то новое? Или способ реализации чего-либо? Где почитать? Заранее спасибо! https://www.cathrinewilhelmsen.net/2015/04/19/table-partitioning-in-sql-server-partition-switching/ https://docs.microsoft.com/ru-ru/sql/t-sql/statements/alter-table-transact-sql?view=sql-server-ver15 Спасибо! Уже читаю... ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2020, 18:11 |
|
блокировки при удалении покрывающего индекса
|
|||
---|---|---|---|
#18+
alexeyvg Да, но он намного быстрее. К слову сказать, truncate имеет очень неприятное ограничение - его вообще нельзя делать на таблице на кторую есть FK, даже если данные это позволяют. Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9.
Msg 4712, Level 16, State 1, Line 9 Cannot truncate table 'a' because it is being referenced by a FOREIGN KEY constraint. И это при том, что обе таблицы вообще пустые. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.10.2020, 20:02 |
|
блокировки при удалении покрывающего индекса
|
|||
---|---|---|---|
#18+
привет, сори что пропал Ребята, спасибо большое суть я уловил, или делаем добавление данных в таблице меняем переключатель и затем потихому удаляем старые данные либо стараемся сделать все оч быстро и эти операции будут ждать освобождения ресурсов На тек момент реализовал truncate + switch (спасибо Yasha123). Далее буду стараться придумать что-то с секционированием, то есть новая секция и switch в нее... ... |
|||
:
Нравится:
Не нравится:
|
|||
26.10.2020, 15:43 |
|
блокировки при удалении покрывающего индекса
|
|||
---|---|---|---|
#18+
Способ обновления таблицы А как очистить/загрузить это просто дешево и сердито. Замечательно работает если данные сильно меняются. А вот если не очень то удалять и перезаписывать всё смысла имеет мало. Попробуйте вместо truncate/insert Код: sql 1. 2. 3. 4. 5. 6. 7. 8.
... |
|||
:
Нравится:
Не нравится:
|
|||
26.10.2020, 17:13 |
|
блокировки при удалении покрывающего индекса
|
|||
---|---|---|---|
#18+
привет резюмирую тут свои выводы и вдруг кому понадобится или же меня поправят Я вижу 2 выхода из этой ситуации 1 - когда мы все же блокируем объект (таблицу) на оч короткое время, очищаем ее и заливаем данные у меня сейчас так и реализовано: Код: sql 1. 2.
при таком подходе плохо, если есть долгоживущие запросы к таблице, к примеру select update delete которые долго выполняются... truncate и alter table (обеим нужен монопольный доступ) будут ждать завершения запросов и только после этого выполнятся (но выполнятся менее чем за 1 секунду) 2 - когда мы переводим базу в режим с уровнем изоляции READ_COMMITTED_SNAPSHOT (ну или SNAPSHOT). При этом мы не будем блокировать select'ами данные, данные будут считываться из снимка на момент ДО внесения в них незакомиченных транзакций за счет версионирования данных (но тут нужно быть осторожным, так как копии данных для select будут попадать в tempdb и она может вырасти, ну и про скорость чтения с tempdb не стоит забывать я думаю). Тогда в таблицу мы добавляем поле Version(ну или любое др название) и присваиваем различные версии для "текущих" и "новых" данных. Текущие данные у нас будут иметь признак Version = 1 (к примеру) Добавляем новые данные с признаком Version = 0 (к примеру) Далее делаем update и заменяем 0 на 1, а 1 на 0 Соответственно во вьюшке мы выбираем только данные where Version = 1 После - удаляем данные из таблицы where Version = 0 (пакетами через top) При этом методе мы с меньшей долей вероятности получим блокировки данных и чтение не будет влиять на этот процесс. То есть процесс обновления будет работать параллельно с работой select'ов и мы не получим остановку работы отчетов или остановку процесса обновления данных Может в чем ошибаюсь, поправьте пожалуйста ... |
|||
:
Нравится:
Не нравится:
|
|||
10.01.2021, 14:43 |
|
блокировки при удалении покрывающего индекса
|
|||
---|---|---|---|
#18+
Sandist Далее делаем update и заменяем 0 на 1, а 1 на 0 Может в чем ошибаюсь, поправьте пожалуйста Дурацкая идея. Update и сопровождающие его блокировки, и запись в журнал. Нафига? Быстрее alter view сделать. А еще проще и также быстро - update 1(одной) строки вспомогательной таблички. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.01.2021, 15:14 |
|
блокировки при удалении покрывающего индекса
|
|||
---|---|---|---|
#18+
aleks222, если пользователи читают из представления, разве alter view не будет ждать пока все обращения к ней не завершаться перед тем как обновиться? по идее мы просто будем ждать так же как если бы сделали truncate и затем switch ... |
|||
:
Нравится:
Не нравится:
|
|||
10.01.2021, 15:20 |
|
блокировки при удалении покрывающего индекса
|
|||
---|---|---|---|
#18+
Sandist, авторА еще проще и также быстро - update 1(одной) строки вспомогательной таблички. то есть в отдельной таблице хранить ту версию которая актуальна и менять одно значение в этой таблице. А во вьюшке уже отбирать версию по этой таблице. Далее удалять все версии которые не соответствуют той что в таблице? правильно понял идею? вроде да, она лучше выходит чем делать update ... |
|||
:
Нравится:
Не нравится:
|
|||
10.01.2021, 15:25 |
|
блокировки при удалении покрывающего индекса
|
|||
---|---|---|---|
#18+
Sandist, я что-то не понял проблемы. А зачем удалять строки в таблице? Не проще ли только помечать их на удаление при MERGE, а уже периодическим заданием зачищать во время низкой нагрузки системы? ... |
|||
:
Нравится:
Не нравится:
|
|||
10.01.2021, 15:28 |
|
блокировки при удалении покрывающего индекса
|
|||
---|---|---|---|
#18+
ptr128, суть в том, что мне не нужны старые данные, я меняю их на новые есть 2 таблицы, в одной лежат текущие данные которые читают пользователи и есть вторая таблица с новыми данные которыми нужно заменит старые если ты про то, что через MERGE менять данные, то их нужно сравнивать, а там сравнивать кучу полей, подозреваю, что будет гораздо медленнее если ты про то, что удалять старые не нужно, то данных довольно немало (4 млн записей) и обновляются они каждые 15 минут, таблица сильно вырастит ... |
|||
:
Нравится:
Не нравится:
|
|||
10.01.2021, 15:36 |
|
блокировки при удалении покрывающего индекса
|
|||
---|---|---|---|
#18+
Sandist, Вы уверены, что меняются каждые 15 минут все четыре миллиона записей? Время затрачиваемое на сравнение двух записей при MERGE точно меньше, чем время затрачиваемое на вставку одной записи. Поэтому, если меняется меньше половины записей, то прирост производительсти Вы точно получите. А накопление даже 200 миллионов записей на удаление за сутки вполне приемлемо для MS SQL. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.01.2021, 15:47 |
|
блокировки при удалении покрывающего индекса
|
|||
---|---|---|---|
#18+
ptr128, да, изменяются около 90% всех записей (но не все поля конечно меняются). Я проверю вариант с merge?может действительно оно того стоит да, можно и 200 млн, но зачем? в этом ведь нет необходимости, мы тратим место + все равно это будет влиять на скорость считывания (секций нет) ... |
|||
:
Нравится:
Не нравится:
|
|||
10.01.2021, 15:50 |
|
блокировки при удалении покрывающего индекса
|
|||
---|---|---|---|
#18+
Sandist, Важно не столько количество записей, в которых меняются поля, сколько количество записей, в которых меняются индексированные поля. Неиндексированные поля можно смело обновлять. А вот при модификации индекса есть шансы заблокироваться. А падение производительности выборок из этой таблицы будет по логарифмическому закону и очень далеко от линейного. Естественно, если выборки не уходят в table scan или clustered index scan. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.01.2021, 15:59 |
|
блокировки при удалении покрывающего индекса
|
|||
---|---|---|---|
#18+
ptr128, на самом деле ключевые поля практически не обновляются, они статичны (в 99.99% случаев) обновляются характеристики которые не имеют отношения к ключу. Я проверю вариант с MERGE и отпишусь ... |
|||
:
Нравится:
Не нравится:
|
|||
10.01.2021, 16:03 |
|
блокировки при удалении покрывающего индекса
|
|||
---|---|---|---|
#18+
Sandist есть таблица А которая имеет примерно 3 млн записей, и которая часто используется пользователями в запросах select (высоко нагруженная) Sandist да, изменяются около 90% всех записей Можно обойтись без переключения секций, мержей, флагов и т.п. Делаете две одинаковые таблицы и синоним, указывающий на одну из них. В запросах используйте синоним. Когда надо переключить данные просто в транзакции пересоздаете синоним с указанием на другую таблицу. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.01.2021, 18:06 |
|
|
start [/forum/topic.php?fid=46&msg=40009228&tid=1685201]: |
0ms |
get settings: |
10ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
159ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
62ms |
get tp. blocked users: |
1ms |
others: | 305ms |
total: | 572ms |
0 / 0 |