![]() |
|
v8: Текст запроса SQL: быстрое удаление объектов | ☑ | ||
---|---|---|---|---|
0
ottto
15.01.10
✎
11:45
|
Потребовалась быстрая удалялка объектов (объектов может удалятся более 10^7). Объекты: справочники, документы.
Естественно в более - менее адекватное время эта задача решается если удалять средствами SQL. Пока задачу решал тупо выполнением через АДО текста SQL-запроса типа "DELETE FROM .. WHERE _IDRRef IN (<список гуидов>) " уперся в ограничение что список определяемый конструкцией (v1,v2.....) по размерности не должен превышать 30000. Ну и собственно такая конструкция работает достаточно долго. Хочется поместить все гуиды во временную таблицу, а затем грохать (поскольку чистить нужно не одну таблицу, а таблицу изменений, таблицы табличных частей и т.д.). Собственно для большей части можно свести задачу к тому, что список удаляемых объектов можно определить результатом 1с-кого запроса. Идея писать конвектор 1с-кого в sql запрос меня не очень прельщает. (определение имен полей и передача параметров в списке - много кода) Есть две идее: 1. 1С -ким запросом получить ссылки поместить в запросе во временную таблицу. Обратится SQL- запросом к сгенерированной временной таблице 2. Создать 1с-кий запрос. определить как он транслируется в SQL. заменить SELECT на DELETE :) Собственно вопросы: как бы определить в какой запрос конвертнулся 1с-кий (программно) как определить имя созданной 1с-ким запросом временной таблицы. |
|||
1
H A D G E H O G s
15.01.10
✎
11:49
|
MS SQL PROFILER
|
|||
2
los_hooliganos
15.01.10
✎
11:50
|
как определить имя созданной 1с-ким запросом временной таблицы.
- если скуль 2005ый, то заипешься с этим. хотя нарабки есть))) |
|||
3
Ненавижу 1С
гуру
15.01.10
✎
11:51
|
некоторые 1С-овские запросы реализуется несколькими SQL-запросами
|
|||
4
los_hooliganos
15.01.10
✎
11:52
|
(3) простой селект напрямую транслируется.
|
|||
5
Ненавижу 1С
гуру
15.01.10
✎
11:53
|
(4) ну самый простой да, но уже с использованием иерархии нет
|
|||
6
H A D G E H O G s
15.01.10
✎
11:54
|
НЕВЗЛЕТИТ
|
|||
7
H A D G E H O G s
15.01.10
✎
11:54
|
(2) Не туда
|
|||
8
H A D G E H O G s
15.01.10
✎
11:54
|
http://www.cyberguru.ru/database/sqlserver/temp-tables.html
Для примера: INSERT INTO #tt1 (_Q_000_F_000RRef) SELECT _Document45_Q_000_T_001._IDRRef AS _Q_000_F_000RRef FROM _Document45 _Document45_Q_000_T_001 WITH(NOLOCK) |
|||
9
H A D G E H O G s
15.01.10
✎
11:54
|
#tt1 а не ##tt1
|
|||
10
Господин ПЖ
15.01.10
✎
11:55
|
truncate table
|
|||
11
los_hooliganos
15.01.10
✎
11:55
|
Автор погугли - Enterprise Integrator
тамма даже видео трассировки есть из 1с. |
|||
12
los_hooliganos
15.01.10
✎
11:56
|
(7) непонял??
|
|||
13
H A D G E H O G s
15.01.10
✎
11:57
|
(12) Даже если узнаешь имя ВТ (из профайлера) - ничего с ней не сделаешь (хм.., может ADO только подцепить), так как 1С оперирует локальными ВТ, а не глобальными
|
|||
14
H A D G E H O G s
15.01.10
✎
11:58
|
Нет, коннект ADO будет считаться уже другим сеансом скорее всего
|
|||
15
los_hooliganos
15.01.10
✎
11:58
|
(13) ну дык надо из под одного сеанса узнавать.
|
|||
16
Sadovnikov
15.01.10
✎
11:58
|
(14) Точно другим.
|
|||
17
los_hooliganos
15.01.10
✎
11:59
|
Короче говорю что заипется, но выход найти можно ;))
|
|||
18
ottto
15.01.10
✎
11:59
|
(1) запуск удаления может производится не обязательно на сервере БД. Потребуется профайлер ставит на клиента, права altertrace и т.д. хочется через адо.
(2) скуль - да 5-й. какие наработки? (3) Думал над этим но думаю всегда можно сделать последний запрос - простеньким) (6) ... не понял:) откуда такая уверенность:) |
|||
19
los_hooliganos
15.01.10
✎
12:00
|
к локальной временной таблице можно обратиться и из другого сеанса, но надо знать её полное имя.
|
|||
20
ottto
15.01.10
✎
12:02
|
(11) смотрел - автор пароль наложил:) - уважаю чужой труд - взламывать не буду
|
|||
21
ottto
15.01.10
✎
12:03
|
(13) да кстати...
пипец |
|||
22
H A D G E H O G s
15.01.10
✎
12:03
|
(19) Нука, подробнее
|
|||
23
los_hooliganos
15.01.10
✎
12:04
|
(21) а ты её глобальной сделай
что мешает?)) |
|||
24
H A D G E H O G s
15.01.10
✎
12:05
|
(21) Тупо:
1) Создать справочник, туда залить в 1С ке все удаляемые ссылки В SQL- фильтр при удалении по этому справочнику. Потом его DROPнуть |
|||
25
H A D G E H O G s
15.01.10
✎
12:05
|
(23) Читай условие задачи
|
|||
26
los_hooliganos
15.01.10
✎
12:05
|
(22) см (23)
|
|||
27
H A D G E H O G s
15.01.10
✎
12:05
|
(26) см (25)
|
|||
28
los_hooliganos
15.01.10
✎
12:06
|
(24) кстати интересный вариант!
|
|||
29
ottto
15.01.10
✎
12:06
|
(24) проблема в том что лимон записей хочется делить хотябы минуты 2.
а так ну его) |
|||
30
ottto
15.01.10
✎
12:06
|
тое есть генерить его часа 3 буду
|
|||
31
ottto
15.01.10
✎
12:07
|
+ не хочется типовую менять)
|
|||
32
los_hooliganos
15.01.10
✎
12:07
|
ну а если свою таблицу запросом сделать?
|
|||
33
ottto
15.01.10
✎
12:08
|
Кстати с регистром сведений может получится - он шустрее пишется и удаляется даже средствами 1с быстро.
(32) как? |
|||
34
los_hooliganos
15.01.10
✎
12:08
|
те берешь селект запрос транслированный, и им через адо сам заливаешь в свою собственную таблицу.
|
|||
35
ottto
15.01.10
✎
12:08
|
я в sql не бум-бум
|
|||
36
H A D G E H O G s
15.01.10
✎
12:08
|
(0) Как ты отделяешь "агнцев от козлищь" ?
|
|||
37
H A D G E H O G s
15.01.10
✎
12:09
|
(35) Сидите уж. Я сам открою...
|
|||
38
los_hooliganos
15.01.10
✎
12:09
|
(35)ну если восмерочный язык запросов знаешь то раберешься))
|
|||
39
ottto
15.01.10
✎
12:11
|
(34) вопрос и был в том как получить транслированный запрос:)
|
|||
40
H A D G E H O G s
15.01.10
✎
12:11
|
(39) MS SQL PROFILER
|
|||
41
Sadovnikov
15.01.10
✎
12:12
|
(38) Шутник...
|
|||
42
ottto
15.01.10
✎
12:12
|
это не разово нужно сделать. процедурка должна быть.
Вместо метода УдалитьОбъекты() будет вывзываться |
|||
43
los_hooliganos
15.01.10
✎
12:13
|
Кстати профайлер можно настроить на запись трассировки во временный текстовый файл, а 1с-ком запросе написать уникальный ключ.
Время от времени парсишь файл профайлера, берешь запрос и вперед.)) |
|||
44
H A D G E H O G s
15.01.10
✎
12:13
|
Интересно вот, а 1С овцы используют локальные ВТ вместо глобальных чтобы не заморачиваться с коллизиями при многопользовательских подключениях? Так ведь сеанс Сервера Приложений - один. Не пойму...
|
|||
45
los_hooliganos
15.01.10
✎
12:14
|
(41) Почему? СКЛ - очень простой язык.))
См в карточке достижения.)) |
|||
46
H A D G E H O G s
15.01.10
✎
12:15
|
Писать аналог УдалитьОбъекты() да еще с контролем ссылочной целостности на SQL - нереально! Поэтому - в 1С ->РегСведений-> из него уже удаляем...
|
|||
47
los_hooliganos
15.01.10
✎
12:16
|
(44) А почему локальные переменные лучше глобальных?
|
|||
48
Sadovnikov
15.01.10
✎
12:16
|
(45) Я лучше на фотографию посмотрю :)
|
|||
49
los_hooliganos
15.01.10
✎
12:16
|
Сразу писали бы все нужные переменные в глобальнике и не парились бы))
|
|||
50
los_hooliganos
15.01.10
✎
12:17
|
Конфигурация то одна))
|
|||
51
ottto
15.01.10
✎
12:17
|
(46) Контроль ссылочности никто не требовал. -удаляемые этой процедуры и справочники на момент удаления будут проверены средствами 1с. Нужно просто грохнуть массив ссылок.
|
|||
52
H A D G E H O G s
15.01.10
✎
12:18
|
(49) Вот и я непонимаю. Давай у Sadovnikov спросим?
|
|||
53
los_hooliganos
15.01.10
✎
12:19
|
(52) Он щас скажет: Потому что восьмерка фуфло!
|
|||
54
Sadovnikov
15.01.10
✎
12:20
|
(52) Чего именно спросим? :)
(53) Ты знал!!! |
|||
55
H A D G E H O G s
15.01.10
✎
12:21
|
З.Ы. А РС лучше чем справочник - так как
1) Нет 3-х индексов по умолчанию присутствующих у справочника 2) Нет контроля уникальности кода 3) Нет генерации ГУИДа |
|||
56
los_hooliganos
15.01.10
✎
12:21
|
Вообщем вопрос из разряда:
Почему нельзя писать SELECT * FROM... в рабочих базах. |
|||
57
H A D G E H O G s
15.01.10
✎
12:21
|
(54) Почему 1С использует локальные а не глобальные ВТ?
|
|||
58
Fester Adams
15.01.10
✎
12:22
|
(57) Непонятно?
|
|||
59
H A D G E H O G s
15.01.10
✎
12:23
|
(58) Поясни
|
|||
60
los_hooliganos
15.01.10
✎
12:23
|
(57) а приколись 2 8ные базы на одном сервере.
и обе создали временные таблицы и... |
|||
61
Fester Adams
15.01.10
✎
12:23
|
(59) Для того что бы не парится с уникальностью имен таблиц.
|
|||
62
H A D G E H O G s
15.01.10
✎
12:25
|
(60) Блиииин, вот я дятелъ. Слона не заметил. :-)
|
|||
63
Sadovnikov
15.01.10
✎
12:25
|
(57) Вот хоть тресни - не помню, как 1С временные таблицы обзывает - GUID или нет?
|
|||
64
ottto
15.01.10
✎
12:26
|
я так понимаю сейчас больше всего людей интересует почему локальные, а неглобальные.
Я воспринимаю такое положение как данность:). Задачу мне нужно решить в таких ограничениях, а решать ее в предположениях вот если бы были глобальными - не носит прикладной характер |
|||
65
Fester Adams
15.01.10
✎
12:26
|
Вообще, если допустим число удаляемых записей из таблицы намного больше оставляемых, то проще выполнить truncate + insert оставляемых.
При операции DELETE лучше использовать INNER JOIN - тогда не надо заморачиваться с ограничениями IN |
|||
66
los_hooliganos
15.01.10
✎
12:27
|
(63) просто #tt1, #tt2 и тд
|
|||
67
Fester Adams
15.01.10
✎
12:28
|
(63) Имя+номер сеанса
|
|||
68
ottto
15.01.10
✎
12:28
|
(65) нет удаляем порядка ^6-^7 остается еще порядка ^7
|
|||
69
rsv
15.01.10
✎
12:30
|
(0) Поместите интрересующие вас ссылки в физическую таблицу. И потом
delete from ОткудаУдаляем where Поле IN (select Поле from ВашаТаблица). |
|||
70
H A D G E H O G s
15.01.10
✎
12:31
|
(68) Случаем не надо удалить все помеченные на удаление, без контроля ссылочной целостности?
|
|||
71
Fester Adams
15.01.10
✎
12:31
|
(68) Это так, для инфо.
|
|||
72
Sadovnikov
15.01.10
✎
12:31
|
(66), (67) Жэсть...
|
|||
73
Fester Adams
15.01.10
✎
12:32
|
(72) Включи технологический журнал и посмотри.
|
|||
74
H A D G E H O G s
15.01.10
✎
12:32
|
(67) Как это соотносится с
#tt1, #tt2 ? |
|||
75
rsv
15.01.10
✎
12:33
|
+(69) delete не быстр. Т.к. пишется инфа еще в лог транзакций. А у Truncate нет условия. Без транзакций но всю таблицу целиком. Так штааааа.
|
|||
76
Fester Adams
15.01.10
✎
12:34
|
(74) Смотря о каких в/т идет речь, я про те, которые сама платформа генерит
|
|||
77
H A D G E H O G s
15.01.10
✎
12:34
|
(76) Я про МенеджерВТ
|
|||
78
ottto
15.01.10
✎
12:35
|
(69) нужно же еще поместить в физ таблицу - это тоже потеря времени.
сейчас 1000000 элементов конструкцией DELETE FROM WHERE _IDRref in (v1,v2...) удаляются приблизительно 20 минут. Нужно бы сократить раз в 5 - 10 |
|||
79
rsv
15.01.10
✎
12:36
|
(78) У вас не будт ограничений как в конструкции IN ('','','','','',''..........)
|
|||
80
los_hooliganos
15.01.10
✎
12:37
|
Как увидеть реальное имя временной таблицы:
select name from tempdb..sysobjects(nolock) where id = (select object_id('tempdb..#tt1')) |
|||
81
ottto
15.01.10
✎
12:38
|
(80) Спасибо..., но как еще 1с-ку заставить выполнить такой код - поскольку нужно то именно из ее сеанса, а не АДО:)
|
|||
82
H A D G E H O G s
15.01.10
✎
12:41
|
(80) Спасибо
|
|||
83
PowerBoy
15.01.10
✎
12:42
|
||||
84
ottto
15.01.10
✎
12:45
|
...открыл смотрю. - вроде сам транслируешь в сиквел.
Я побоялся с этим связываться:) |
|||
85
ottto
15.01.10
✎
12:47
|
и почему-то условие по списку значений не работает.
|
|||
86
PowerBoy
15.01.10
✎
12:50
|
||||
87
Axel2009
15.01.10
✎
12:54
|
(0) убить все индексы кроме кластерного и удалять.
"Собственно для большей части можно свести задачу к тому, что список удаляемых объектов можно определить результатом 1с-кого запроса." нафига тогда во временную таблицу помещать? пищите сразу delete с запросом. если скуль 2005, то там можно delete top 10000 from bla-bla-bla |
|||
88
Axel2009
15.01.10
✎
13:01
|
(81) обращаться к локальным временным таблицам из другого сеанса нельзя.
|
|||
89
Axel2009
15.01.10
✎
13:02
|
(78) преобразовать к виду
delete from ОткудаУдаляем inner join (select Поле from ВашаТаблица) on IN поле = поле. |
|||
90
ottto
15.01.10
✎
13:03
|
(86) посмотрел транслятор.
Не работает когда разыменовываешь более чем на одно поле. Например: Запрос: ВЫБРАТЬ Номенклатура.Ссылка ИЗ Справочник.Номенклатура КАК Номенклатура ГДЕ Номенклатура.Родитель.Код В ("1111", "222") Транслируется в: Select Nomenklatura._IDRRef From _Reference30 As Nomenklatura Where Nomenklatura.Roditelyy.Kod In ( '1111' , '222' ) Собственно глюк: Nomenklatura.Roditelyy.Kod А так удаление 1000000 заняло 5 минут. - приемлимый результат. |
|||
91
Axel2009
15.01.10
✎
13:06
|
(90) запусти технологический журнал и будет тебе щастье. там каждый запрос 1сный записывается в файл и какой из него получается скульный.
|
|||
92
Axel2009
15.01.10
✎
13:07
|
(19) и с каких это пор можно к локальной временной таблице одного сеанса, обратиться из другого?
|
|||
93
ottto
15.01.10
✎
13:08
|
(89) проблема в том что временной таблицы нет.
ее нужно генерировать запросами - а как менее накладно ее сгенерировать это для меня БОЛЬШОЙ вопрос. (91) мне нужен не разовый запрос... а процедурка УдалитьМногоОбъектов заменитель метода УдалитьОбъекты. |
|||
94
Axel2009
15.01.10
✎
13:11
|
(93)
1. менее накладно ее не генерировать. а удалять порциями. 2. разово ты узнаешь откуда все удаляется. а потом уже этот запрос тянуть в продолжение. |
|||
95
ottto
15.01.10
✎
13:25
|
(94) ну вот не совсем так.
В обработке (86) насколько я понял получается временная таблица и потом данные херятся по конструкцией delete from ... where _iddref in (select _iddref from #table1) результат 3-5 минут если херить порционно: 333 раз по delete from ... where _iddref in (v1,...v30000) то 20 минут. (больше 30000 размер списка сделать нельзя - оптимизатор просит упростить запрос) |
|||
96
Axel2009
15.01.10
✎
13:26
|
(95) а IN использовать нельзя. потому как индексы не используются. нужно как в (89)
|
|||
97
ottto
15.01.10
✎
13:30
|
Смотрю план запроса вроде впорядке все
Cluster Index Seek выполняется ровно 1 раз на 30000 порцию. |
|||
98
Axel2009
15.01.10
✎
13:30
|
delete top 3000 from ОткудаУдаляем t1 inner join (select _iddref from #table1) t2 on IN t1._iddref = t2._iddref
только на таблицу #table1 навесить индекс по полю _iddref |
|||
99
Axel2009
15.01.10
✎
13:31
|
а как его съедает оптимизатор?
вызов на каждую строку @p1 or @p2 or @p3 и т.д. 30000 раз, и вызов на каждую строку. |
|||
100
Aleksey_3
15.01.10
✎
14:40
|
(100)
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |