NNS на тему загрузки ресурсов при планах обслуживания:
1. У вас в планах обслуживания стоит шаг "Реорганизация индекса". Тут есть тонкость :
Инструкция, которая при этом выполняется "ALTER INDEX ... REORGANIZE" - она всегда однопоточная, и не умеет в много ядер.
(Подтверждение от Microsoft)
Именно поэтому её применяют только если степень фрагментации индекса <30%.
Если Степень фрагментации >30% применяют "ALTER INDEX ... REBUILD" который умеет в многопоточность, но он более ресурсоёмкий, по сути это полное перестроение индекса.
(Определение фрагментации и выбор способа обслужива...)
Чтобы работало корректно без динамик sql тут не обойтись. (Не обязательно именно этот использовать, это лишь первый из поиска, можно поискать другие.
Проверил на тестовых базах REORGANIZE - реально всегда однопоточный, и если создавать план обслуживания с ИТС (Реорганизация индекса) , он, похоже, всегда будет в 1 поток.
unfilled, думаю соглашусь, если она не сказывается на производительности и влезет в тех. окно, то от неё будет польза, тут наверно мой опыт больших баз немного переклинил. Согласен, неправ. Лучше делать, но опять же зависит от обстоятельств.
unfilled, я же написал "Особенно если база крупная" , если у вас БД, размером 3ТБ+ checkdb происходит 16+ часов (Если повезет). при этом блокируя таблицы на час и более. Вы серьёзно в таком состоянии будете держать продакшн на ежедневной основе ? и по какой причине у вас будет повреждение БД, если на работе пользователей это не сказывается и проблем нет ? Checkdb - это довольно ресурсоёмкая операция, и на ежедневной основе на крупных базах, смысла особого не имеет. Ну и обычно если какие-то проблемы с таблицами есть, они проявятся в работе запросов, или при перестроении индексов и решаться они будут или "AllowdataLoss" или бэкапом предыдущего периода.
NNS ну да, можно назвать и так ) ... в любом случае это всё, только вершина айсберга, темы "Анализ и оптимизация производительности 1С + MSSQL" ... интересуйтесь, пробуйте, потенциал большой. (Если всё это не оч поможет, почитайте про "Тех журнал 1С", ожидания на блокировках, Запросы и планы запросов в 1С и MSSQL ... всё это поможет понять "Почему эта гадина тормозит" )))
NNS на самом деле если мы вернемся к изначальной теме вопроса, "Пользователи жалуются что медленно" и "Я сам вижу что тормозит", я бы вам посоветовал в первую очередь смотреть не на MSSQL а на 1С. Т.к. обычно основные тормоза именно в коде 1С.
Как пример можете "Косвенно" повлиять на разнесение пользователей на разные процессы (временно).
Т.е. если дело в 1С тогда это может помочь разобраться в проблеме. порядок такой :
1. Вы обнаружили что вот прям щас происходит серьёзная просадка по производительности. (Необычно долго отрабатывают стандартные действия, с падением производительности более 30% от стандартного времени выполнения.
2. Заходите в консоль кластера 1С.
3. Переходите на вкладку рабочие процессы вашего кластера, запоминаете PID и смотрите на колонку "Включен" , там скорее всего будет значение "Да".
4. Правый клик по кластеру, => свойства.
5. Ставите "Интервал перезапуска рабочих процессов" некоторый период, например 100 сек.
жмете "Ок". переходите на вкладку рабочие процессы, и жмете обновить пока ваш изначальный рабочий процесс (С PID который вы запомнили) не получит значение в колонке "Включен" = "Нет".
6. Правый клик по кластеру, => свойства. => ставите обратно интервал перезапуска рабочих процессов = 0.
ОК.
картинка на раб процессах будет примерно такая :
Таким образом если в текущий момент у вас выполняется какая-то длительная и сложная операция, которая мешает пользователям, она останется на старом процессе, и как только она завершится, старый процесс отвалится. Пользователи в это время (как только старый будет помечен как не включен) будут "Переезжать" на новый процесс, при этом в системе будет подвисание всех на 1-10 сек. после того как пользователи переедут на новый процесс, (Можно увидеть на вкладке "Сеансы" по колонке "Процесс", там будет у живых пользователей PID нового процесса) Проверьте производительность. Если "Станет лучше" тогда смотрите вкладку сеансы и ищите, кто остался со старым PID. Скорее всего это будет какое-то регл. задание типа расчета себестоимости или распределение взаиморасчетов или ещё что. Это и есть виновник тормозов. дальше уже что с ним делать вопрос 2-й ...
Это один из вариантов определения тормозных операций в 1С.
P.S.: при этом возможна сложность - люди , сидящие под толстым клиентом, или те, кого сервер не сможет пересадить на новый процесс, могут получить сообщение "Сеанс завершен администратором". Это нужно учитывать. Но если никакого криминала они не делают, всё должно быть Ок.
На тему DOP, с помощью настройки вы можете "Косвенно" влиять на загрузку ЦП, т.е. изначаль сам MSSQL решает сколько ресурсов для выполнения того или иного запроса, а параметрами MAXDOP и Cost threshold (Степень параллелизма и стоимостной порог) вы можете ему ограничить эти хотелки. Если поставить 0 (Крайне не рекомендуется) чтобы снять ограничения, но использовать все ядра или нет , все равно решать будет ядро MSSQL. если стоит DOP 1 тогда или в запросе обслуживания стоит хинт "With maxdop (1)" (См свойства задания, и сгенерированный скрипт настроенного плана) или таблицы настолько маленькие, что распараллеливать их нет смысла.
NNS да, перезагрузка не требуется, но распараллеливание начнётся со следующей транзакции (т.е. текущая транзакция реиндекса дойдёт со старыми настройками, реиндекс след. таблицы пойдёт по новому плану.
В любом случае, направление в котором вы можете "Копать" в сторону ускорения примерно следующее :
1. Определить узкое место (железо, блокировки 1с/SQL, ожидания исполнения команд по типам)
2. Исправление узких мест (причем исправление одного может вызвать выстрел другого места, это цикличный процесс).
По вкладке ожидания ресурсов, вроде проблем быть не должно. Возможно сам запрос реиндекса не оптимальный, его часто делают не через "План обслуживание" а через "Регл задание сервера" с произвольным запросом. т.е. ребилдить не всё что есть, а то что требует ребилда/дефрага. В инете куча SQL запросов для определения что сейчас конкретно необходимо в конкретной ситуации. (до 30% фрагментации = дефраг индекса, более = ребилд индекса) если менее 15% то можно пока что не трогать.
Константин если честно сомнительные утверждения, а именно :
"2.количество процессов для 1С вообще не интересно" - если пользователей до 20 тогда думаю да ... если вы на одном процессе будете считать себестоимость/взаиморасчеты, и на этом же процессе будут пользователи, вы увидите серьёзные просадки. Разнесение тяжелых операций и пользователей по разным процессам решает эту проблему (именно поэтому 1С в последних версиях платформы вывела опцию "Количество сеансов на процесс" в Enterprise версию сервера, который стоит дорого.)
"3) переиндексация ... эффекта нет никакого." - серьёзно?
- При неактуальной статистике будут некорректные и неоптимальные планы на MSSQL ... это может увеличивать время выполнения запроса в разы.
- При фрагментации индекса более 70% - будут table/index scan вместо index seek это тоже будет медленней в разы.
Ну если нужно только текстом "Описать" как это должно выглядеть ... можете попробовать нечто типа 1С:Бухгалтерия. Там это всё реализовано и есть куча описаний как работают механизмы.
Если нужно её реализовать, тут будет сложнее, хотя вопрос в масштабах системы, и куче условностей. Например если вам нужно сделать "Личный финансовый калькулятор", который будет собирать чеки с смс-ок и вам выдавать отчет в произвольной форме, тогда там вроде как должно быть не сложно ... если же вам нужно комплексную систему с регл. отчетностью ... тут могут быть "сложности".
BorLaze, возможно я не совсем правильно понял условия задачи, или вы :
в заголовке "чтобы активной единовременно могла быть только одна запись"
в теле "У меня есть переключение активных записей на фронте."
В таком случае поправлюсь : Если речь про то, чтобы в таблице всегда была только одна запись активная, тогда думаю ваш вариант прокатит... если их больше 1-й и речь идёт об одной активной в рамках какого-то измерения (например Name) тогда скорее всего придётся :
- сначала получить группы и последние даты, а затем получать данные из этих дат.
Например, если таблица такого вида(изначально):
ID, NAME, Instance, ACTIVATED
1, Andrew, UK, 1
2, Andrew, US, 0
3, Andrew, DE, 0
4, Boris, US, 1
5, Boris, UK, 0
6, Boris, DE, 0
То после применения даты в поле ACTIVATED получим :
ID, NAME, Instance, ACTIVATED
1, Andrew, UK, 2021-02-01
2, Andrew, US, 2021-01-02
3, Andrew, DE, 2021-01-01
4, Boris, US, 2021-01-31
5, Boris, UK, 2021-01-02
6, Boris, DE, 2021-01-01
В этом случае активна получается только запись UK ... а чтобы это узнать необходимо сначала получить макс по полю ACTIVATED, а затем уже узнать данные из строки (Instance)
Это решение подходит только для конкретных задач, например если надо брать последнюю информацию по ключевым полям. Хотя даже в этом случае сначала придётся получить дату последней записи. Если задача встанет "просуммируй активные записи", представьте ваш запрос, а в случае с флагом добавится только условие Where active = true.
Я так понимаю это работает аналогично оконным функциям ? (т.е. на уровне движка это будут доп. запросы к таблице источнику ?
"from items i
left join item_fields fi on i.id = fi.item_id and fi.id in (218, 219, 220)"
получается это не совсем Pivot ? т.е. результат сопоставимый, но по производительности медленней ?
Melkij, ясно спасибо, честно говоря, до этого момента ни разу не сталкивался с идентификаторами в двойных кавычках, обычно они без кавычек совсем (Из того что я видел).
P.S. Про то, что это строка были мысли из аналогии с 1С. В 1С двойные кавычки это явный указатель на тип строка.
Сергей Горностаев, ОФФТОП: можт подскажете как спец по PG:
А что за прикол в PG с алиасами на примере этого запроса (я сам с mssql больше) LEFT JOIN :choice_category choice_category
, тут понятно таблица + алиас.
а вот так это фишка PG ? LEFT JOIN :user "user"
(т.е. алиас указан как тип строка, от этого есть какой-то выигрыш ? или в чем смысл алиас делать строкой ? ... прост увидел "user".*
Выглядит как выбери все поля из строки о_О wtf ...
т.е. в текущей реализации "чтобы условия прописывались один раз для всех полей...." похоже не получится ...
только если Coalesce подойдет (попробуй можт там и впрям Null в пустых колонках) иначе для каждой придётся прописывать ...
а вообще, у тебя большие проблемы со структурой БД ...
поидее навер должно было быть несколько таблиц типа
nom -- Список номенклатуры
levels -- Таблица ярусов
Koefs -- Таблица коэффициентов
Тогда таблица sost имела бы всего 3 или 4 колонки ... и 3 соединения ... в результате получил бы тоже самое , но без подобных "Монструозных" конструкций ...
Реляционности в этой таблице - не много ...
в pg "unPivot" - вроде нет (но это не точно, я с pgsql не часто работаю)
Если поправить структуру, тогда и запросы будут лакончинее и быстрее, и места поменьше будет занимать ... а так ... похоже совсем красиво не получится ... но это совсем другая история
1. У вас в планах обслуживания стоит шаг "Реорганизация индекса". Тут есть тонкость :
Инструкция, которая при этом выполняется "ALTER INDEX ... REORGANIZE" - она всегда однопоточная, и не умеет в много ядер.
(Подтверждение от Microsoft)
Именно поэтому её применяют только если степень фрагментации индекса <30%.
Если Степень фрагментации >30% применяют "ALTER INDEX ... REBUILD" который умеет в многопоточность, но он более ресурсоёмкий, по сути это полное перестроение индекса.
(Определение фрагментации и выбор способа обслужива...)
Чтобы работало корректно без динамик sql тут не обойтись. (Не обязательно именно этот использовать, это лишь первый из поиска, можно поискать другие.
Проверил на тестовых базах REORGANIZE - реально всегда однопоточный, и если создавать план обслуживания с ИТС (Реорганизация индекса) , он, похоже, всегда будет в 1 поток.