Иногда в процессе разработки сталкиваешься с задачей удаления строк из таблицы значений по некоторому условию.
Стало интересно, а какие вообще способы есть, и как они ведут себя с точки зрения оптимизации.
Хотел провести свое минирасследование, а оказывается doom2good на инфостарте уже такое провел. Как говориться, доверяй, но проверяй. Поэтому я провел аналогичные тесты и получил результаты близкие к тем, которые приведены в статье.
Помещаем таблицу значений во временную таблицу в запросе, далее выполняем запрос и выгружаем результат в новую таблицу значений.
Обходим нашу таблицу и по условию удаляем строки. Реализация может быть и другого вида, сначала обходим таблицу, складываем удаляемые строки в массив, потом обходим этот массив и удаляем строки.
Создаем массив, обходим таблицу значений, по некоторому положительному условию добавляем строки в наш массив и далее вызываем метод таблицы значений «Скопировать», куда передаем массив с нужными строками.
Создаем новую пустую таблицу значений с аналогичным составом колонок. Далее обходим исходную таблицу и по некоторому положительному условию добавляем строки в новую пустую таблицу методом.
В исходную таблицу добавляем колонку «ОставлятьСтроку», с типом булево. Обходим таблицу значений, проверяем условие, и если строку нам нужно оставить, устанавливаем признак «Истина». Далее вызываем метод «Скопировать» у таблицы значений с отбором «ОставлятьСтроку» = Истина. Далее удаляем добавленную колонку.
Если в исходной таблице значений уже есть колонка, по которой однозначно можно сделать отбор, вызываем метод «Скопировать» у таблицы значений с этим отбором.
Итак, результаты расположил в порядке убывания от самого быстрого к самому медленному.
1️⃣ Выгрузка с отбором. Самый быстрый способ. Работает быстро, когда нужно удалить как малое количество строк, так и большое количество строк.
2️⃣ Предобработка и выгрузка с отбором. Если нужно удалить большое количество строк, то этот способ на втором месте. А вот если нужно удалить малое количество строк, например <2%, то способ «Удаление строк по условию» будет немного быстрее, но разница менее 10% в выигрыше времени.
3️⃣Копирование таблицы. Этот способ немного уступает «Предобработка и выгрузка с отбором» по времени, но разница не более 10%.
4️⃣ Копирование строк. Этот способ на больших объемах немного уступает копированию таблицы.
5️⃣ Удаление строк по условию. Еще раз повторюсь, этот способ хорош, когда удаляемых строк мало, но если их много, то данный способ может отрабатывать даже дольше, чем удаление строк через запрос.
6️⃣ Удаление строк через запрос. Способ хорош, когда необходимо удалить строки с некоторым сложным условием, например, если в условии отбора участвуют данные из других таблиц и нужно выполнить соединение с этими таблицами. При этом самый медленный.
На моем оборудовании не получилось прогнать тест с количеством записей ~ 1.000.000 записей в таблице значений. Основным узким местом стал именно процессор, хотя изначально я предполагал, что это будет оперативная память. Один сеанс и один rphost, который загрузил бедное ядро на 💯%, при том что другие ядрышки простаивают...
Окончания теста с 1.000.000 записями я так и не дождался, ограничился результатами максимум на 100.000.
Также я провел замеры на 10.000 записей по использованию памяти (MemoryPeak) и процессорного времени (CpuTime), и получилось следующее:
👉🏻 Удаление строк по условию: кушает меньше всего памяти за серверный вызов, а также минимально использование процессорного времени, но разница со вторым местом в пределах 10%.
👉🏻 Удаление строк через запрос: кушает больше всех памяти, примерно в 2 раза по MemoryPeak. Процессор при этом как в других способах. Тут мы также нагружаем сервер СУБД своей временной таблицей.
Остальные способы +/- одинаково используют память и процессорное время.
>>Click here to continue<<
