|
А интересно как вы удаляете строки из таблицы значений. | ☑ | ||
---|---|---|---|---|
0
Keyn
05.01.16
✎
08:49
|
А интересно как вы удаляете строки из таблицы значений. Надеюсь что не так: ТаблицаЦен.Удалить(Индекс); (взял пример из хелпа)
Работать конечно будет просто медленно. Когда вы удаляете так как в хелпе, то 1Ска удалит строку и сдвинет остальные строки "вверх". А это медленный процесс. Если у вас большая таблица значений и удалить нужно много строк, это может занять время, а ждать не хочется, поэтому можно воспользоватся хитростью. Добавляем в таблицу значений новую служебную колонку. В эту колонку каждому удаляемому значению ставим 1. Затем сортируем по этой колонке и все удаляемые значения окажутся в конце. (сортировка же делается быстро) Затем спокойно удаляем все начиная с конца, и в этом случае 1Ске не придется "сдвигать" строки. И такое удаление будет быстрым. Вот такой код у меня получился: // Очень быстро! Удаляет строки из таблицы значений, но только те строки в которых есть переданное значение // ТЗ - таблица значений // Колонка - идентификатор колонки в которой будет осуществлятся поиск Значения. // Значение - значение которое будем удалять // ЗначениеОставить - 1 означает что нужно оставить в таблице переднанное Значение, а остальные удалить // 0 наоборот, удалить из таблицы переданное Значение Процедура УдалитьСтрокиИзТЗ(ТЗ,Колонка,Значение,ЗначениеОставить=0) Экспорт НадаУдалять=0; ТЗ.Колонки.Добавить("СЛУЖДЛЯУДАЛЕНИЯ"); Если ЗначениеОставить=0 Тогда Для каждого СтрокаТЗ Из ТЗ Цикл Если СтрокаТЗ[Колонка]=Значение Тогда СтрокаТЗ.СЛУЖДЛЯУДАЛЕНИЯ=1; НадаУдалять=1; КонецЕсли; КонецЦикла; Иначе Для каждого СтрокаТЗ Из ТЗ Цикл Если СтрокаТЗ[Колонка]<>Значение Тогда СтрокаТЗ.СЛУЖДЛЯУДАЛЕНИЯ=1; НадаУдалять=1; КонецЕсли; КонецЦикла; КонецЕсли; Если НадаУдалять=1 Тогда ТЗ.Сортировать("СЛУЖДЛЯУДАЛЕНИЯ"); Индекс=ТЗ.Количество()-1; Пока Индекс>=0 Цикл Если ТЗ[Индекс].СЛУЖДЛЯУДАЛЕНИЯ=1 Тогда ТЗ.Удалить(Индекс); Иначе Прервать; КонецЕсли; Индекс=Индекс-1; КонецЦикла; КонецЕсли; ТЗ.Колонки.Удалить("СЛУЖДЛЯУДАЛЕНИЯ"); КонецПроцедуры писал код давно еще на заре выхода 8.0. и да я знаю как пишется слово надо |
|||
1
Маратыч
05.01.16
✎
08:51
|
А насколько быстрее, не замерялось? Чот терзают меня смутные сомнения, что весь этот комплект операций будет работать быстрее, чем некий "сдвиг" строк ТЗ в памяти при удалении через индекс.
|
|||
2
Рэйв
05.01.16
✎
08:52
|
у меня самый простой метод.Сначала нахожу все строки которые надо удалить и складываю их в список.
Потом пробегаю список и Таб.Удалить(ЭлементСписка.Значение) |
|||
3
Рэйв
05.01.16
✎
08:52
|
ну или если возможно одним условием, то получаю в массив через .НайтиСтроки()
|
|||
4
Keyn
05.01.16
✎
08:53
|
конечно же замерялось. к сожалению не могу привести сейчас ссылку. но этот способ один из быстрых. есть и другие)
|
|||
5
tank68
05.01.16
✎
09:25
|
Можно не в запрос передать таблицу как переменную
Ошибка = Ложь; Текст = "Загрузка почтовых ящиков, указанных сотрудниками на ВнешняяТаблицаДанных."; ЗапросПочтаНаВнешняяТаблицаДанных = Новый Запрос; ЗапросПочтаНаВнешняяТаблицаДанных.Текст = "ВЫБРАТЬ | dbo_UserEmail.LDAP, | ВЫБОР | КОГДА ЕСТЬNULL(dbo_UserEmail.EMail1, ""0"") = ""0"" | ТОГДА ЕСТЬNULL(dbo_UserEmail.EMail2, ""0"") | ИНАЧЕ ЕСТЬNULL(dbo_UserEmail.EMail1, ""0"") | КОНЕЦ КАК ПочтаВнешняяТаблицаДанных |ИЗ | ВнешнийИсточникДанных.Intraru.Таблица.dbo_UserEmail КАК dbo_UserEmail |ГДЕ | ВЫБОР | КОГДА ЕСТЬNULL(dbo_UserEmail.EMail1, ""0"") = ""0"" | ТОГДА ЕСТЬNULL(dbo_UserEmail.EMail2, ""0"") | ИНАЧЕ ЕСТЬNULL(dbo_UserEmail.EMail1, ""0"") | КОНЕЦ <> ""0"""; ПочтаНаВнешняяТаблицаДанных = ЗапросПочтаНаВнешняяТаблицаДанных.Выполнить().Выгрузить(); Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | UserEmail.LDAP КАК LDAP, | UserEmail.ПочтаВнешняяТаблицаДанных КАК ПочтаНаВнешняяТаблицаДанных |ПОМЕСТИТЬ ТаблицаСПочтой |ИЗ | &UserEmail КАК UserEmail | |ИНДЕКСИРОВАТЬ ПО | LDAP |; | |//////////////////////////////////////////////////////////////////////////////// |ВЫБРАТЬ | ФизическиеЛица.Ссылка, | ТаблицаСПочтой.LDAP, | ТаблицаСПочтой.ПочтаНаВнешняяТаблицаДанных |ИЗ | Справочник.ФизическиеЛица КАК ФизическиеЛица | ЛЕВОЕ СОЕДИНЕНИЕ ТаблицаСПочтой КАК ТаблицаСПочтой | ПО ФизическиеЛица.LDAP = ТаблицаСПочтой.LDAP |ГДЕ | ТаблицаСПочтой.ПочтаНаВнешняяТаблицаДанных <> ФизическиеЛица.ЭлектроннаяПочтаВнешняяТаблицаДанных"; Запрос.УстановитьПараметр("UserEmail",ПочтаНаВнешняяТаблицаДанных); Таблица = Запрос.Выполнить(); Выборка = Таблица.Выбрать(); #Если ТолстыйКлиентОбычноеПриложение Тогда Процессор = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений; Процессор.ОтображатьПроцентВывода = Истина; Процессор.НачатьВывод(); Элемент = Новый ЭлементРезультатаКомпоновкиДанных; #КонецЕсли Колво = Выборка.Количество(); НомерПП = 0; Пока Выборка.Следующий() Цикл Попытка НомерПП = НомерПП+1; #Если ТолстыйКлиентОбычноеПриложение Тогда Состояние(" Обрабатывается "+НомерПП+ " из "+Колво); Элемент.ПроцентВывода = НомерПП/Колво*100; Процессор.ВывестиЭлемент(Элемент); #КонецЕсли Если НомерПП = Цел(НомерПП/100)*100 Тогда Сообщить(""+ТекущаяДата()+" Обработано:"+СокрЛП(НомерПП)); КонецЕсли; Об = Выборка.Ссылка.ПолучитьОбъект(); Об.ЭлектроннаяПочтаВнешняяТаблицаДанных = Выборка.ПочтаНаВнешняяТаблицаДанных; Об.Записать(); Исключение ТекстОшибки = (""+ТекущаяДата()+" Сотрудник "+СокрЛП(Выборка.Ссылка)+" почта на ВнешняяТаблицаДанных " + СокрЛП(Выборка.ПочтаНаВнешняяТаблицаДанных)+" ошибка: "+ОписаниеОшибки()); Сообщить("--------------------------------------"); Сообщить(ТекстОшибки,СтатусСообщения.ОченьВажное); Сообщить("--------------------------------------"); Ошибка = Истина; Текст = Текст+Символы.ПС+Символы.ПС+ТекстОшибки; КонецПопытки; //Сообщить("Для сотрудника "+СокрЛП(Выборка.Ссылка)+" необходимо указать почту " + СокрЛП(Выборка.ПочтаНаВнешняяТаблицаДанных)); КонецЦикла; #Если Клиент Тогда Процессор.ЗакончитьВывод(); #КонецЕсли |
|||
6
tank68
05.01.16
✎
09:26
|
(5) А в запросе соответственно с этой таблицей что угодно делать, в запросе это быстрее делается чем в цикле
|
|||
7
Маратыч
05.01.16
✎
09:30
|
Костылестроение 80 лвл...
|
|||
8
tank68
05.01.16
✎
09:31
|
(7) Попробуй миллион строк перебрать в цикле и попробуй отобрать запросом я посмотрю как быстрее получиться
|
|||
9
Мимохожий Однако
05.01.16
✎
09:40
|
(0)важно для чего используется эта таблица значений потом. Может быть, в дальнейшем идёт перебор и достаточно поставить фильтр и продолжить для обработки. На просторах инета есть куча примеров. Я так и не понял, для чего создана ветка.
|
|||
10
Маратыч
05.01.16
✎
09:49
|
(8) От постановки задачи зависит. Я вообще постараюсь не допустить миллиона строк в ТЗ еще на этапе получения этих данных.
|
|||
11
Euguln
05.01.16
✎
10:09
|
(0) Забавно, а сортировка процесс на порядок сложнее, чем сдвиг строк. Об этом не задумывался?
|
|||
12
SeraFim
05.01.16
✎
10:20
|
Если есть возмножность отобрать все удаляемые строки через НайтиСтроки(), то делаю через неё.
В Противном случае - цикл в обратном направлении |
|||
13
User_Agronom
05.01.16
✎
10:34
|
За год, наверное, уже 10я тема про удаление строк из ТЗ.
Чаще бывает только про очистку ТЗ. Сбивается ли выборка ? |
|||
14
tank68
05.01.16
✎
10:43
|
(10) Ну вообще если не делать через такие вещи платформа сама начинает оптимизировать запрос и не всегда оптимально поэтому временные таблицы в запросе в большинстве случаев гораздо быстрее работает чем перебирать данные в цикле
http://catalog.mista.ru/public/153851/ Книга знаний: Временные таблицы в 8.1 |
|||
15
Garykom
гуру
05.01.16
✎
10:43
|
(13) ну не умеют поиском пользоваться. поэтому и не знают что самый быстрый способ удаления строк, это создание новой ТЗ с переносом туда тех что не нужно удалять
|
|||
16
tank68
05.01.16
✎
10:47
|
(15) Все надеяться что в новой версии что то новое не описанное ранее
|
|||
17
Живой Ископаемый
05.01.16
✎
11:01
|
||||
18
strange2007
05.01.16
✎
11:47
|
Не понимаю в чём спор. Проверить то можно минут за несколько.
№1 (удаление без сортировок, пернебирая каждую строку). 10000 записей: 0,083600 100000 записей: 0,930294 №2 (сначала пометка удаляемых строк, потом сортировка и удаление): 10000 записей: 0,088318 100000 записей: 0,935507 База файловая, платформа 8.3.7 |
|||
19
strange2007
05.01.16
✎
11:51
|
+(18) Код выложить? Как его жёлтый плюсик обернуть?
|
|||
20
Злопчинский
05.01.16
✎
12:22
|
Восьмерочники открывают для себя клюшечные азы
Прикольненько |
|||
21
zak555
05.01.16
✎
12:25
|
(20) ты 17 посмотри
|
|||
22
strange2007
05.01.16
✎
12:34
|
(21) Смотрел. У автора был конкретный вопрос, тема уже более 3-х часов висит, вот я и сделал замер минут за 15 для автора
|
|||
23
zak555
05.01.16
✎
12:39
|
(22) делай замер на
ОбъектДокумента = Документ.ПолучитьОбъект(); КритерийОставленияСтрок = Новый Структура(); КритерийОставленияСтрок .Вставить("КакаяТаКолонка", КакоеТоЗначение) ОбъектДокумента.Товары.Загрузить(ОбъектДокумента.Товары.Загрузить(ОбъектДокумента.Товары.НайтиСтроки(КритерийОставленияСтрок))); |
|||
24
strange2007
05.01.16
✎
12:50
|
(23) Сам делай)))))) Я для (0) сделал и выложил результаты замеров. Если надо что-то кому-то доказать или оптимизировать свой алгоритм, то пусть сам и замеряет скорость.
Эх, теоретики... |
|||
25
Nirvana
17.01.16
✎
00:15
|
Это в небольших таблицах значений сортировка делается быстро.
А в огромных таблицах сортировка - чуть ли не самая медленная операция. |
|||
26
ifso
17.01.16
✎
01:05
|
(25) главное не озвучивай, что при сортировке строки сдвигаются, а то мало ли что ^^
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |