|
Удаление из большой таблицы. Как?
|
|||
---|---|---|---|
#18+
Доброго времени суток. Столкнулся с проблемой переноса данных в историческую базу. Задача. имеем таблицу с 300 миллионами+ записями есть два поля, год и квартал, по которым можно определить что вырезаем, а что оставляем. Фактически 2/3 данных нужно перенести в другую таблицу и удалить в первоначальной. ddl таблицы которая требует обрезки create table dbo.tbl_store ( id numeric(18, 0) identity, year_ smallint not null, qq_ tinyint not null, member_id numeric(18, 0) not null, complect_code varchar(20) not null, chances decimal(14, 10) not null, state tinyint DEFAULT 0 not null, num smallint not null, shop_del tinyint null, constraint PKtbl_store_id PRIMARY KEY NONCLUSTERED ( id ) ) lock datarows on 'default' go print 'XXmembID' create nonclustered index XXmembID on dbo.tbl_store (member_id) on 'default' print 'XXmemb_num_state' create nonclustered index XXmemb_num_state on dbo.tbl_store (member_id, num, state) on 'default' Индексы строить не вариант на полях year_ и qq_, так как происходит залочка и вообщем пользователи плачут. Программисту который такое сваял, тоже уже ничего не поможет. Пробовал вариант с временной таблицей. Создаю временную таблицу, ставлю SET rowcount 100 после чего закидываю в нее данные из родительской. Данные в таблице находятся по порядку. То есть самые старые в начале и тд. Затем полученные данные из времянки. по условию к примеру, 2012 год и 2 квартал, делаю инсерт в историческую базу в таблицу. после этого удаляю из родительской. Код: 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. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88.
Проблема в том что все это ну очень долго происходит, и к примеру за один квартал - это 30 лямов, выгружается около 10%, после чего закачивается место в tempdb. Запускаю через *.bat isql. Гуру подскажите плиз какие есть варианты решения проблемы? Adaptive Server Enterprise/12.5.4/EBF 16791 ESD#10/P/NT (IX86)/OS 4.0/ase1254/2159/32-bit/OPT/Mon Nov 02 05:01:55 2009 ... |
|||
:
Нравится:
Не нравится:
|
|||
19.01.2015, 15:55 |
|
Удаление из большой таблицы. Как?
|
|||
---|---|---|---|
#18+
kostik88, Задачка тривиальная, несколько вариантов решения может быть. Из быстрых: 1) создать view1 для исторических данных 2) выгрузить её (select ... from view1) в файл1 с помощью BCP 3) создать view2 для данных, которые должны остаться в исходной таблице 4) выгрузить её (select ... from view2) в файл2 с помощью BCP 5) truncate исходной таблицы 6) удалить на ней индексы 7) залить в нее файл2 с помощью BCP 8) построить индексы обратно 9) в историческую таблицу залить файл1 с помощью BCP, удалив индексы и создав их обратно после заливки предварительно почитать про режимы BCP : http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc30191.1550/html/utility/X20696.htm ... |
|||
:
Нравится:
Не нравится:
|
|||
19.01.2015, 18:53 |
|
Удаление из большой таблицы. Как?
|
|||
---|---|---|---|
#18+
Предложение хорошее, в бытность работы с MS SQL Server я бы так и поступил, но тут меня смущает процесс постоения индексов на таблице со 100 миллионами записей. Сколько это будет по времени, и будут же залочки во время создания индексов, и пользователи жаловаться будут. А окна технологического нету :(. Но я все же попробую в тестовой среде предложенный Вами вариант. Спасибо. А какие есть еще варианты ? ... |
|||
:
Нравится:
Не нравится:
|
|||
19.01.2015, 22:10 |
|
Удаление из большой таблицы. Как?
|
|||
---|---|---|---|
#18+
kostik88Предложение хорошее, в бытность работы с MS SQL Server я бы так и поступил, но тут меня смущает процесс постоения индексов на таблице со 100 миллионами записей. Сколько это будет по времени, и будут же залочки во время создания индексов, и пользователи жаловаться будут. А окна технологического нету :(. Но я все же попробую в тестовой среде предложенный Вами вариант. Спасибо. А какие есть еще варианты ? На вскидку, разной степени простоты и трудозатратности: * Базу в режим truncate log on checkpoint, удалять батчами. * Создать рядом вторую таблицу, перелить туда нужные данные, построить индексы, после этого переименовать объекты - старую таблицу и новую поменять местами; провести рекомпиляцию связанных объектов; из переименованной перелить исторические данные в историческую таблицу. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2015, 01:18 |
|
Удаление из большой таблицы. Как?
|
|||
---|---|---|---|
#18+
kostik88Предложение хорошее, в бытность работы с MS SQL Server я бы так и поступил, но тут меня смущает процесс постоения индексов на таблице со 100 миллионами записей. Сколько это будет по времени, и будут же залочки во время создания индексов, и пользователи жаловаться будут. А окна технологического нету :(. Но я все же попробую в тестовой среде предложенный Вами вариант. Спасибо. А какие есть еще варианты ? Привет! Все варианты, которые подразумевают прозрачный для пользователей перенос будут длительны во времени. Поправим немного план komrad'a, тем более что во втором посте он намекает... 1) создать view1 для исторических данных 2) выгрузить её (select ... from view1) в файл1 с помощью BCP 3) в историческую таблицу залить файл1 с помощью BCP, удалив индексы и создав их обратно после заливки 4) Выбрать время минимальной загрузки (ночь, ранее утро etc) и удалять исторические данные конструкцией delete top 10000 from... в while (@@rowcount != 0) Да, это займет время, но прозрачно для пользователей. (не забудь включить обрезание лога по чекпоинту в базе) ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2015, 14:40 |
|
Удаление из большой таблицы. Как?
|
|||
---|---|---|---|
#18+
SQLMantisПривет! Все варианты, которые подразумевают прозрачный для пользователей перенос будут длительны во времени. Поправим немного план komrad'a... с корректировкой согласен, тем более что мой вариант был схематичным SQLMantisДа, это займет время, но прозрачно для пользователей. (не забудь включить обрезание лога по чекпоинту в базе) решение об автоматическом обрезании лога на продакшен базе требует некоторого размышления от автора "только трусы делают дампы" (с) начальник ;) ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2015, 22:27 |
|
Удаление из большой таблицы. Как?
|
|||
---|---|---|---|
#18+
Спасибо друзья за советы! Буду осуществлять на практике! ... |
|||
:
Нравится:
Не нравится:
|
|||
21.01.2015, 09:14 |
|
Удаление из большой таблицы. Как?
|
|||
---|---|---|---|
#18+
kostik88, Код: sql 1.
Логично предположить, что дата у вас линейно зависима на Id , т.е. чем больше Id тем больше дата и не может быть двух записей с ID1 > ID2 , в которых Date2 < Date1 . По Id есть индекс. Задача сводится к удалению по ID . Делаете процедуру (без представлений и пр.), которая: 1. Копирует батч (X записей) в архивную таблицу по диапазону ID: ID between N1 and N2 , при этом ID < MaxID (само собой количество записей между N1 и N2 должно быть больше либо равно X для снижения количества иттераций) . Где MaxId соответствует идентификатору записи с максимальной датой, которую можно удалить - найти этот MaxId думаю не составит труда для вас. Архивная таблица имеет признак на каждой записи, типа HaveDeleted / WhenDeleted с индексом по этому полю. При копировании, поле равно 0. 2. Батчем удаляете записи из основной, у которых ID соответствует записям из архивной с признаком HaveDeleted = 0 . 3. Апдейтите архивную: записи с HaveDeleted = 0 на HaveDeleted = 1 если соответствующий ID не найден в основной таблице. С виду монстрообразная конструкция, не самая оптимальная по быстродействию, но позволит: а) переносить данные в архив мелкими партиями по Х записей - не блокирую других пользователей. б) удалять данные из основной таблицы партиями по Х1 записей (при этом Х <> Х1), опять же не блокируя пользователей и обеспечивая приемлемую нагрузку на сервер/лог/таблицу, учитывая все особенности вашей системы. в) "развести" процесс копирования и удаления по времени, тем самым "разгрузив" систему. К примеру, копирование может быть "грязным" и вообще без локов (старые данные же у вас не меняются? Так ведь?). Удаление можно проводить в периоды низкой нагрузки системы, вплоть до одной записи. г) обеспечить целостность данных - ничего не теряете в итоге. д) растянуть процесс во времени, если система 24х7 - нет необходимости в простое. При желании копирование и удаление могут быть разведены по двум независимым процессам - но тут надо аккуратно подходить - дабы процессы друг друга не блокировали. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.01.2015, 11:01 |
|
Удаление из большой таблицы. Как?
|
|||
---|---|---|---|
#18+
Mikle83, похоже воспользуюсь именно вашим советом, так как вариант с bcp отпадает, так как база куда будут помещены исторические данные, находится под репликацией и разрешено только bcp-выкачка данных. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.01.2015, 11:48 |
|
Удаление из большой таблицы. Как?
|
|||
---|---|---|---|
#18+
kostik88Mikle83, похоже воспользуюсь именно вашим советом, так как вариант с bcp отпадает, так как база куда будут помещены исторические данные, находится под репликацией и разрешено только bcp-выкачка данных. Тут давайте остановимся, посчитаем до 10 и Вы нам расскажите по подробнее про "база находится под репликацией" ... |
|||
:
Нравится:
Не нравится:
|
|||
21.01.2015, 12:08 |
|
Удаление из большой таблицы. Как?
|
|||
---|---|---|---|
#18+
SQLMantis, Подробнее, есть два сервера БД, издатель и подписчик. 4 базы на каждом, все они под репликацией. Какие вопросики будут ? ... |
|||
:
Нравится:
Не нравится:
|
|||
21.01.2015, 12:28 |
|
Удаление из большой таблицы. Как?
|
|||
---|---|---|---|
#18+
kostik88SQLMantis, Какие вопросики будут ? Как реализована репликация? Какими средствами? ... |
|||
:
Нравится:
Не нравится:
|
|||
21.01.2015, 15:14 |
|
Удаление из большой таблицы. Как?
|
|||
---|---|---|---|
#18+
SQLMantis, настроен RS 15.7 ... |
|||
:
Нравится:
Не нравится:
|
|||
21.01.2015, 16:46 |
|
Удаление из большой таблицы. Как?
|
|||
---|---|---|---|
#18+
kostik88SQLMantis, настроен RS 15.7 Круто :) warm standby? ... |
|||
:
Нравится:
Не нравится:
|
|||
21.01.2015, 16:59 |
|
Удаление из большой таблицы. Как?
|
|||
---|---|---|---|
#18+
SQLMantis, простите? Я только несколько месяцев работаю с данной БД и репликатором. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.01.2015, 17:56 |
|
Удаление из большой таблицы. Как?
|
|||
---|---|---|---|
#18+
SQLMantis, простите? Я только несколько месяцев работаю с данной БД и репликатором. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.01.2015, 09:59 |
|
Удаление из большой таблицы. Как?
|
|||
---|---|---|---|
#18+
kostik88SQLMantis, простите? Я только несколько месяцев работаю с данной БД и репликатором. Тогда, пока ничего не трогайте. А то мы тут насоветовали много такого от чего переполняются logsegment'ы и пухнут очереди в RS. Перво наперво нужно узнать участвует ли ваша таблица в репликации. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.01.2015, 14:23 |
|
Удаление из большой таблицы. Как?
|
|||
---|---|---|---|
#18+
SQLMantiskostik88SQLMantis, простите? Я только несколько месяцев работаю с данной БД и репликатором. Тогда, пока ничего не трогайте. А то мы тут насоветовали много такого от чего переполняются logsegment'ы и пухнут очереди в RS. Перво наперво нужно узнать участвует ли ваша таблица в репликации. Ну вот. И так в топике про Sybase - скучно, так еще и потенциальную тему "упала репликация" - срубили :( По теме - если есть репликация => +1 к варианту с процедурой. В начале указать отключение репликации на сессию. Запуск раздельный на primary и на подписчике(ах). Возможна рассинхронизация данных между архивными таблицами и "архивных" данных в основной, но, скорее всего, это не критично для бизнес задач - надо уточнять у ваших аналитиков/бизнеса. В любом случае, никто не мешает собрать представление с UNION обоих таблиц и завязать всю отчетность на представление, если это реально критично. Можно и не тушить репликацию, как раз за счет батчей снизить нагрузку, обернуть все в отдельные транзакции... Но есть предположение, что нет у вас полноценного тестового сервера с настроенной репликацией, что не позволит полноценно отладить процессы до внедрения схемы в прод. P.S.: на архивируемую таблицу другие не ссылаются случаем? ... |
|||
:
Нравится:
Не нравится:
|
|||
22.01.2015, 15:40 |
|
Удаление из большой таблицы. Как?
|
|||
---|---|---|---|
#18+
Спасибо всем кто откинулся на мой вопрос! На счет репликации, под ней все и таблицы и прочие объекты и тд. Таблица которую буду "резать", так же под репликацией, но она статична до порезки, и в нее на момент порезки никто добавлять ничего не будет. Просто нужно что бы в этой таблице был некий период, а остальное в хистори-базу. Так что тут все ок. На счет отключения репликации. Планирую обернуть процедуру через sp_setrepproc Оформил я так как предложил Mikle83, завернул в процедуру. Процедура Код: 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. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69.
... |
|||
:
Нравится:
Не нравится:
|
|||
22.01.2015, 17:13 |
|
Удаление из большой таблицы. Как?
|
|||
---|---|---|---|
#18+
kostik88, Код: sql 1. 2.
странно это... Реально есть уверенность, что у вас нет "пропусков" в идентификаторах? Я делал что-то типа (с точностью до синтаксиса) Код: sql 1. 2. 3. 4. 5. 6. 7. 8.
Такой подход позволял нивелировать "пропуски" в идентификаторах и переносить в каждой иттерации +/- одинаковое количество записей, делая процесс более предсказуемым. c DELETE рисковано, на мой взгляд делать так: Код: sql 1. 2. 3. 4.
Я бы удалял то, что гарантированно перенесено в архив Код: sql 1. 2. 3.
Опять же, структура HasDeleted может оказаться полезной, если объем удаляемых записей не совпадает с объемом выборки на копирование. Если в вашем случае возможен вырожденный случай и эти два объема идентичны - крупно повезло, можно оставить и так... ... |
|||
:
Нравится:
Не нравится:
|
|||
22.01.2015, 17:36 |
|
Удаление из большой таблицы. Как?
|
|||
---|---|---|---|
#18+
Mikle83, Код: sql 1. 2.
поставил только для той ситуации, если случайно будет запущенно дважды. Плохой вариант ? На счет остальных подсказок, еще раз сенкс. Покручу с их учетом. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.01.2015, 17:59 |
|
Удаление из большой таблицы. Как?
|
|||
---|---|---|---|
#18+
Mikle83 В начале указать отключение репликации на сессию. Хмм. Можно поподробнее, что предлагается сделать? ... |
|||
:
Нравится:
Не нравится:
|
|||
22.01.2015, 18:09 |
|
Удаление из большой таблицы. Как?
|
|||
---|---|---|---|
#18+
SQLMantisMikle83 В начале указать отключение репликации на сессию. Хмм. Можно поподробнее, что предлагается сделать? к примеру следующий запрос в начале процедуры: Код: sql 1. 2.
все что будет "твориться" внутри процедуры не пойдет на реплику. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.01.2015, 11:00 |
|
Удаление из большой таблицы. Как?
|
|||
---|---|---|---|
#18+
kostik88поставил только для той ситуации, если случайно будет запущенно дважды. Плохой вариант ? Смотря как будете Min/Max определять для передачи в процедуру. по мимо варианта повторного запуска, возможно (особенно при последовательном переборе значений ИД), что наткнетесь на иинтервал [Min;Max] в котором нет записей. Процедура отработает с ексепшеном. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.01.2015, 11:03 |
|
Удаление из большой таблицы. Как?
|
|||
---|---|---|---|
#18+
Mikle83, на счет удаления данных, я же беру некоторое количество записей, копирую их в хистори таблицу, и тут же по этому же диапазону произвожу удаление данных. Далее, изменение структуры таблицы увы не допустимо. Это на счет флага для скопированных записей. На счет отключения репликации, а это процедура sp_setrepproc разве не сделает то же самое? То есть я оберну выполнение своей процедуры через эту функцию, и отдельно запущу на издателе и подписчике. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.01.2015, 12:23 |
|
|
start [/forum/topic.php?fid=55&msg=38857671&tid=2009784]: |
0ms |
get settings: |
10ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
55ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
56ms |
get tp. blocked users: |
2ms |
others: | 14ms |
total: | 172ms |
0 / 0 |