Ускорить ВЫБРАТЬ КОЛИЧЕСТВО(*) ИЗ РегистрСведений.<> [Вопрос 1С Эксперт]
Задача с экзамена 1С Эксперт. (частично обсуждение было )
Текст задачи:
"В базе работают 1000 пользователей. Есть регистр сведений в нем 100 млн записей. запрос select count выполняется t= 60 сек. Необходимо сделать так, чтобы данные были получены за t = 1c."
Можете ли Вы подсказать, пожалуйста, в каком направлении мыслить/искать? Преподаватель говорит, есть порядка 12 способов решить задачу.
Коллеги отвечали преподавателю (Александру Морозову) по-разному, мы заранее придумали что можно отетить и отвечали
1) требуется выполнение всех регламентных операций, дефрагментация, реиндексация
2) требуется создание некластерного индекса или сделать регистр таким, чтобы был хотя бы один некластерный индекс, т.к. scan по нему быстрее скана по кластерному индексу
Первые два совета недостаточны.
3) Пробовали ответить, что нужно хранить заведомо где-то количество в этом регистре, типо константы и при записи наборов записей или удалении - следить за тем, сколько у нас записей (жертвуем записью ради запроса по выбору количества записей) - тоже не подходит
4) Коллеги предлагали из DMV представлений или статистики получать значение - тоже преподаватель говорит нарушение лиц.соглашения, нельзя в обход rphost подключаться к SQL базе напрямую
5) может быть нужно секционирование предложить было? Но Вы писали где-то, что его оч.сложно настроить и нужны знания сертифицированного специалиста MS SQL
6) Может быть надо MDOP = 1 выставить? Т.к. если 60 секунд выполняется сканирование - может быть происходит блокировка параллельных сканов или что-то такое.
7) Мы предлагали преподавателю перестроить бизнес-логику решения. Тоже не "прокатило".
Если подскажете, что можно было бы сделать, или где почитать (направление), очень многие люди будут благодарны!
Сейчас это задание как триггер, отсеиватель, добрая часть людей отсеивается просто в самом конце экзамена:)
Спасибо!!!
Текст задачи:
"В базе работают 1000 пользователей. Есть регистр сведений в нем 100 млн записей. запрос select count выполняется t= 60 сек. Необходимо сделать так, чтобы данные были получены за t = 1c."
Можете ли Вы подсказать, пожалуйста, в каком направлении мыслить/искать? Преподаватель говорит, есть порядка 12 способов решить задачу.
Коллеги отвечали преподавателю (Александру Морозову) по-разному, мы заранее придумали что можно отетить и отвечали
1) требуется выполнение всех регламентных операций, дефрагментация, реиндексация
2) требуется создание некластерного индекса или сделать регистр таким, чтобы был хотя бы один некластерный индекс, т.к. scan по нему быстрее скана по кластерному индексу
Первые два совета недостаточны.
3) Пробовали ответить, что нужно хранить заведомо где-то количество в этом регистре, типо константы и при записи наборов записей или удалении - следить за тем, сколько у нас записей (жертвуем записью ради запроса по выбору количества записей) - тоже не подходит
4) Коллеги предлагали из DMV представлений или статистики получать значение - тоже преподаватель говорит нарушение лиц.соглашения, нельзя в обход rphost подключаться к SQL базе напрямую
5) может быть нужно секционирование предложить было? Но Вы писали где-то, что его оч.сложно настроить и нужны знания сертифицированного специалиста MS SQL
6) Может быть надо MDOP = 1 выставить? Т.к. если 60 секунд выполняется сканирование - может быть происходит блокировка параллельных сканов или что-то такое.
7) Мы предлагали преподавателю перестроить бизнес-логику решения. Тоже не "прокатило".
Если подскажете, что можно было бы сделать, или где почитать (направление), очень многие люди будут благодарны!
Сейчас это задание как триггер, отсеиватель, добрая часть людей отсеивается просто в самом конце экзамена:)
Спасибо!!!
По теме из базы знаний
Ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
Вид сервера БД имеет значение или нет?
Т.е. это вопрос на тюнинг настроек конкретного сервера БД или на придумывание механизма?
Т.е. это вопрос на тюнинг настроек конкретного сервера БД или на придумывание механизма?
(7)
вообще вопрос каcаемо MSSQL, но потом спрашиваю что может измениться на PostgreSQL
(11)
Мне кажется что нет т.к. для 8.3 будет использоваться RCSI и читающие транзакции не будут блокировать друг друга.
Вид сервера БД имеет значение или нет?
Т.е. это вопрос на тюнинг настроек конкретного сервера БД или на придумывание механизма?
Т.е. это вопрос на тюнинг настроек конкретного сервера БД или на придумывание механизма?
вообще вопрос каcаемо MSSQL, но потом спрашиваю что может измениться на PostgreSQL
(11)
Интересно, для чего сказано что 1000 пользователей? Как то с блокировками связано?
Мне кажется что нет т.к. для 8.3 будет использоваться RCSI и читающие транзакции не будут блокировать друг друга.
(19)
Если два пользователя начнут добавлять (удалять) записи из этого регистра, то они станут в очередь на изменение
Регистр периодический или нет? В него можно добавить ресурс или реквизит, в котором сохранять общее количество записей (в момент записи). Потом отбирать только последнюю запись.
Если два пользователя начнут добавлять (удалять) записи из этого регистра, то они станут в очередь на изменение
ресурса или реквизита, в котором будет храниться общее количество записей
(20)Ресурс в разных строках. Если регистр периодический, то в 8.3 если не ошибаюсь есть таблица итогов, тогда да. НО! Вам ведь нужно ускорить чтение, а это может быть куплено ценой более долгой записи. Поэтому пусть встанут. Поправьте если не прав.
может кто нибудь проверить на больших таблицах?:
И
ВЫБРАТЬ
СУММА(1) КАК Количество
ИЗ
Справочник.Контрагенты КАК Контрагенты И
ВЫБРАТЬ
Количество(*) КАК Количество
ИЗ
Справочник.Контрагенты КАК Контрагенты
(1)
Дедуктивный метод:
Пока пришёл к выводу, что не сделать никак! ( при учёте, что именно необходимо выполнить запрос в 1С - не прямой)
"В базе работают 1000 пользователей. Есть регистр сведений в нем 100 млн записей. запрос sel ect count выполняется t= 60 сек. Необходимо сделать так, чтобы данные были получены за t = 1c."
Дедуктивный метод:
Пока пришёл к выводу, что не сделать никак! ( при учёте, что именно необходимо выполнить запрос
select count(*) Fr om Table
На форуме Гилева говорится
"разумные решения заключаются в том чтобы не сканировать таблицу в 100 миллионов строк"
Отсюда вывод что нужно сканировать частями.
На своей практики использую такой метод для быстрой очистки регистра сведений "Версии объектов" множественными фоновыми заданиями.
"разумные решения заключаются в том чтобы не сканировать таблицу в 100 миллионов строк"
Отсюда вывод что нужно сканировать частями.
На своей практики использую такой метод для быстрой очистки регистра сведений "Версии объектов" множественными фоновыми заданиями.
Кстати сходил по ссылке в топике на форму Гилева, там писали что преподаватель требовал решить это штатными средствами платформы. Причем как я понял дополнительные константы или отдельные регистры тут создавать нельзя. Новые константы / регистры создавать не вариант, новые индексы не проходят. А что тогда вообще остается из штатных средств платформы?
(23)Как это? Прочитать в объектной технике? Вряд ли это будет быстрее, тут что-то более хитрое должно быть, в идеале нужно уйти от сканирования таблицы в 100 млн записей, но вот как? Все попытки перенести уже посчитанные данные в другой объект конфигурации экзаменатор отвергает, настройка доп. индексов тоже не подходит, прямое обращение к базе SQL минуя сервер 1С тоже нельзя.
(55)
метод РегистрСведенийМенеджер.<Имя регистра сведений>.Выбрать (InformationRegisterManager.<Имя регистра сведений>.Select)
формирует объект РегистрСведенийВыборка.<Имя регистра сведений> (InformationRegisterSelection.<Имя регистра сведений>)
в описании которого сказано
Объект этого типа возвращается методами Выбрать и ВыбратьПоРегистратору у объекта типа РегистрСведенийМенеджер. и представляет собой специализированный способ перебора записей регистра сведений.
Обход записей выполняется системой динамически. Это означает, что использование выборки не считывает все записи сразу, а выбирает их порциями из базы данных. Такой подход позволяет достаточно быстро обходить с помощью выборки большое количество записей и не загружать в память всех элементов выборки.
источник - синтакс помошник
А можно ссылку на источник?
метод РегистрСведенийМенеджер.<Имя регистра сведений>.Выбрать (InformationRegisterManager.<Имя регистра сведений>.Select)
формирует объект РегистрСведенийВыборка.<Имя регистра сведений> (InformationRegisterSelection.<Имя регистра сведений>)
в описании которого сказано
Объект этого типа возвращается методами Выбрать и ВыбратьПоРегистратору у объекта типа РегистрСведенийМенеджер. и представляет собой специализированный способ перебора записей регистра сведений.
Обход записей выполняется системой динамически. Это означает, что использование выборки не считывает все записи сразу, а выбирает их порциями из базы данных. Такой подход позволяет достаточно быстро обходить с помощью выборки большое количество записей и не загружать в память всех элементов выборки.
источник - синтакс помошник
Знать точное количество порядка 100 млн записей - априори бред. На практике изменение логики неизбежно. Гилев верно ставит краеугольный вопрос "для чего это нужно?".
Но здесь как я понимаю чисто теоретическая плоскость решения? Фраза 12 способов меня поставила в тупик... Что же это за теоретические решения такие?
Но здесь как я понимаю чисто теоретическая плоскость решения? Фраза 12 способов меня поставила в тупик... Что же это за теоретические решения такие?
А если попытаться написать запрос так, чтобы MS SQL его распараллелил.
Программно сформировать текст запроса например для всех значений первого измерения. А потом объединить.
Программно сформировать текст запроса например для всех значений первого измерения. А потом объединить.
Т.е. рефрен будет где-то такой:
ВЫБРАТЬ КОЛИЧЕТСВО(*) ИЗ РегистрСведений.НашРегистр КАК Таблица1 ГДЕ Таблица1.Измерение1 = &Значение1
ВЫБРАТЬ КОЛИЧЕТСВО(*) ИЗ РегистрСведений.НашРегистр КАК Таблица1 ГДЕ Таблица1.Измерение1 = &Значение1
(36) ну на самом деле можно смастрячить регламентное задание которое будет получать это значение и сохнаять его в хранилище настроек. А пользователи будут его оттуда брать, но им потребуется права дать на получение чужих настроек
(49)Не прокатит, подобное на экзамене предлагали, преподаватель отвечал что будут примерные данные, а ему нужны точные (уж не знаю зачем). Я так понял что все формы кэширования/предварительного расчета отвергаются по этой причине.
(48)Это всё хорошо, но вот что писали на форуме Гилева:
Смущает добавление "средствами платформы". Знать бы что имели в виду, может быть какую-то реструктуризацию таблиц в конфигураторе сделать.
Добрый день.
На экзамене задали такой же вопрос. Уточнения:
Сначала спросили про MSSQL в полном режиме совместимости (Read Commited Snapshot). Каждый из 1000 пользователей хочет получить точное количество записей из регистра, запрос выполняется 60 секунд. Как "средствами платформы" получить целевое время выполнения в 1 секунду?
На экзамене задали такой же вопрос. Уточнения:
Сначала спросили про MSSQL в полном режиме совместимости (Read Commited Snapshot). Каждый из 1000 пользователей хочет получить точное количество записей из регистра, запрос выполняется 60 секунд. Как "средствами платформы" получить целевое время выполнения в 1 секунду?
Смущает добавление "средствами платформы". Знать бы что имели в виду, может быть какую-то реструктуризацию таблиц в конфигураторе сделать.
Пробовал еще вставить во времянку Выбрать 1 из регистра и прочитать количество через Запрос.ВыполнитьПакет() - ожидаемо медленно. Но убедиться стоило тоже.
В порядке бреда:
попробовать через ODATA: /Catalog_Номенклатура?$count
вдруг, оно там как-то по-своему реализовано?
PS. сам с OData ещё не работал, не довелось :(
попробовать через ODATA: /Catalog_Номенклатура?$count
вдруг, оно там как-то по-своему реализовано?
PS. сам с OData ещё не работал, не довелось :(
В postgreSQL - предлагают тригер, типа как подписка на событие после добаление/удаление, инкрементировать / декрементировать счётчик.
Мож в 1С тоже подписку нужно и в константу!?
Мож в 1С тоже подписку нужно и в константу!?
неправильный код....
Номер строки это номер строки ТЧ регистратора.
Номер строки это номер строки ТЧ регистратора.
Выбрать Первые 1
номерстроки
из регистрсведений.ЦеныНоменклатуры
упорядочить по номерстроки убыв
Народ! а если некоторые варианты приведенные выше(включая Количество(*)) заключить в
конечно понимаю что вопрос может быть глуп. а вдруг?
НачатьТранзакцию();
ЗафиксироватьТранзакцию();конечно понимаю что вопрос может быть глуп. а вдруг?
(70) вот тоже думаю каким образом.... у меня просто проверить не на чем...
нет больших регистров.
нет больших регистров.
НачатьТранзакцию();
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| КОЛИЧЕСТВО(*) КАК Поле1
|ИЗ
| РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры";
ТКОЛ = Запрос.Выполнить().Выгрузить();
Сообщить(ТКОЛ[0].Поле1);
ОтменитьТранзакцию(); Показать
По условию, нужно найти способ, при котором получение количества записей регистра станет работать в 60 раз быстрее.
При этом:
1) база в разделенном режиме (1000 пользователей)
2) запрос 1С остается штатный
3) бизнес-логику менять нельзя
4) использования индекса недостаточно (что понятно - некоторый прирост будет, но не в 60 раз)
Я склоняюсь к тому, что речь о каких-то фокусах со стороны настроек СУБД. Причем в реальном продакшене вряд ли применимых (ибо чудес не бывает).
При этом:
1) база в разделенном режиме (1000 пользователей)
2) запрос 1С остается штатный
3) бизнес-логику менять нельзя
4) использования индекса недостаточно (что понятно - некоторый прирост будет, но не в 60 раз)
Я склоняюсь к тому, что речь о каких-то фокусах со стороны настроек СУБД. Причем в реальном продакшене вряд ли применимых (ибо чудес не бывает).
О! Может, надо как раз без RCSI? В этом случае ЕМНИП раньше в 1С (еще при автоматических блокировках) нетранзакционное чтение выполнялось WITH NOLOCK
Посмотрели у себя на базе. Регистр 1 млн записей - 40 мс.
Т.е. если было 100 млн, то было бы примерно 4 с. При это Количество(*) и выборка всех значений первого измерения одинаковы.
Сейчас к этому регистру не обращаются, т.е. блокировок не было.
Может вопрос и в блокировках при записи
Тогда уж лучше отложенные движения.
Как вариант вопрос не на знания, а на подход? Если запрос крутить, то это не подход эксперта, т.к. нужно выяснить комплексную причину.
Т.е. если было 100 млн, то было бы примерно 4 с. При это Количество(*) и выборка всех значений первого измерения одинаковы.
Сейчас к этому регистру не обращаются, т.е. блокировок не было.
Может вопрос и в блокировках при записи
Тогда уж лучше отложенные движения.
Как вариант вопрос не на знания, а на подход? Если запрос крутить, то это не подход эксперта, т.к. нужно выяснить комплексную причину.
Ну вот в MSSQL в режиме блокировочника на большой таблице в разделенном доступе в самом деле будет большая разница между SELECT COUNT(*) и SELECT COUNT(*) WITH (NOLOCK) даже в READ COMMITTED
Возможно информация поможет: попробовал в своей рабочей базе на регистре цен номенклатуры, результат в прикрепленном скриншоте, первый раз запрос отрабатывал 3 секунды, потом чаще всего меньше 0,5 секунды, но была пара "выбросов" за 1 секунду. Баз рабочая, в том числе и в этот регистр идет активная запись/чтение данных.
Прикрепленные файлы:
Статистика была такая:
Длительность формирования результата - 328 мс
Длительность формирования результата - 343 мс
Длительность формирования результата - 2 403 мс
Длительность формирования результата - 437 мс
Длительность формирования результата - 327 мс
Длительность формирования результата - 452 мс
Длительность формирования результата - 530 мс
Длительность формирования результата - 327 мс
Длительность формирования результата - 702 мс
Длительность формирования результата - 296 мс
Длительность формирования результата - 374 мс
Длительность формирования результата - 312 мс
Длительность формирования результата - 312 мс
Длительность формирования результата - 421 мс
База УПП, MSSQL, режим совместимости с 8.2, толстый клиент.
Длительность формирования результата - 328 мс
Длительность формирования результата - 343 мс
Длительность формирования результата - 2 403 мс
Длительность формирования результата - 437 мс
Длительность формирования результата - 327 мс
Длительность формирования результата - 452 мс
Длительность формирования результата - 530 мс
Длительность формирования результата - 327 мс
Длительность формирования результата - 702 мс
Длительность формирования результата - 296 мс
Длительность формирования результата - 374 мс
Длительность формирования результата - 312 мс
Длительность формирования результата - 312 мс
Длительность формирования результата - 421 мс
База УПП, MSSQL, режим совместимости с 8.2, толстый клиент.
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот
