Інтернет Windows Android

Як знайти входження символу в рядку 1с. На що схожа реалізована нами схема

У даній статті я розповім вам про функцію швидкого пошуку 1С Підприємство 8. Що таке швидкий пошук? Дуже просто. Швидкий пошук - це один із способів навігації у великих списках записів 1С. Це можуть бути списки документів, довідники, регістри - все те, що представлено таблицями.

Що таке швидкий пошук?

Функція швидкого пошуку в документах 1С Підприємство надзвичайно зручна і дозволяє не перегортати величезні масиви даних (наприклад, за допомогою смуги прокрутки), а відразу перейти до потрібного місця в списку. На жаль, починаючі користувачі 1С Підприємство 8 (в тому числі і 1С Бухгалтерія 8) спочатку не використовують можливості швидкого пошуку, вважаючи за краще перегортати списки документів вручну (а вони можуть бути дуже великими). Дана стаття допоможе вам розібратися з використанням швидкого пошуку в 1С.

Перш за все слід зауважити, що в конфігураціях 1С Підприємство 8, побудованих на керованих формах, швидкий пошук працює інакше, ніж в попередніх версіях 1С. Тому розберемо окремо використання швидкого пошуку в керованих формах і в звичайних.

Швидкий пошук в 1С Бухгалтерія 8.2

У версіях 1С Бухгалтерія з 8.0 по 8.2 функція призначена саме для переходу до потрібної частини списку. Для прикладу подивіться на вікно плану рахунків, наведене на малюнку.


У вікні виділена деяка рядок. Зверніть увагу малопомітний трикутник зі смужок, на який вказує червона стрілка. Як і в інших програмах Windows, де є списки (наприклад, в Провіднику), положення цього маркера (трикутника) визначає сортування списку в цілому - в якій колонці встановлений маркер, по тій і буде відсортований весь список. На малюнку маркер стоїть в колонці Код, отже рахунки в плані рахунків будуть відсортовані за кодом.

Маркер можна переміщати з однієї колонки на іншу, клацаючи на потрібній колонці ( на заголовку колонки!) Мишкою. Якщо маркер і так вже стоїть в поточній колонці, то клацання призведе до зміни напрямку сортування на протилежне (тобто від більшого до меншого або навпаки). Це стандартна поведінка для будь-яких програм Windows. У чому ж особливість цього маркера в 1С Підприємстві і як це пов'язано з швидким пошуком?

Швидкий пошук в списках 1С Підприємство 8 здійснюється по колонці, в якій стоїть маркер. В даному випадку швидкий пошук в плані рахунків буде здійснюватися по колонці Код.

тут була важлива частина статті, але без JavaScript її не видно!

Як користуватися швидким пошуком в 1С? Легко! Просто почніть друкувати те, що хочете знайти в ЦІЙ колонці, Тобто там, де стоїть маркер. У прикладі на малюнку вище слід вводити номер рахунку. Наприклад, ви хочете знайти рахунок 50 Каса. У такому випадку введіть ( мишкою клацати нікуди не потрібно!) Число 50 з клавіатури і якщо в цій колонці є рахунок з таким номером (а він, звичайно, є), то список прокрутиться до цього рядка, а сама рядок виявиться виділеної. Результат показаний на скріншоті плану рахунків нижче.

сайт_

Текст, на який вказує стрілка, прати потім не потрібно - він сам зникне.

Якщо в наведеному прикладі почати вводити слово "Каса", то текст в нижній частині вікна буде вводиться, а потім стиратися. Відбувається це тому, що як тільки початок введеної рядки швидкого пошуку перестає збігатися з початком хоча б одного рядка в даному стовпчику, 1С Підприємство робить висновок, що шукана рядок не знайдена і автоматично її стирає. У зв'язку з цим слід запам'ятати два правила.

В 1С Підприємстві 8 швидкий пошук проводиться по початку рядка, тобто в колонці шукається збіг тексту, що вводиться з початком однієї з рядків цієї колонки.
Звідси випливає важлива рекомендація: при введенні даних в довідники називайте елементи так, щоб їх було зручно шукати за допомогою швидкого пошуку. Наприклад, назва контрагента краще писати як "ІмяФірми ТОВ", ніж "ТОВ ІмяФірми". І тим більше не варто використовувати в назві лапки та інші непотрібні символи (мова йде про заповнення поля Найменування в формах).

Якщо ви почали вводити текст, а він стирається - то, що ви шукаєте, відсутній в даному стовпчику! В цьому випадку перевірте мову введення, а також колонку в якій виробляється швидкий пошук. Типова помилка - обрана не та колонка. Наприклад, маркер встановлено в колонці Код, а пошук здійснюється за назвою рахунку.

Швидкий пошук в 1С Бухгалтерія 8.3

Тепер подивимося, чим відрізняється швидкий пошук у версії 1С Підприємство 8.3. Використання багато в чому схоже з версією 8.2, проте є одна істотна відмінність, яке слід запам'ятати.

В 1С Бухгалтерія 8.3, а також в будь-яких інших конфігураціях на керованих формах (той самий новий інтерфейс), Працює як фільтр. Простіше кажучи, в результаті роботи функції швидкого пошуку частину списку ховається.

Як цим користуватися, ми з вами зараз з'ясуємо. Для початку подивіться на скріншот вікна плану рахунків 1С Бухгалтерія 8.3, наведений нижче.

сайт_

Як бачите, той же самий маркер в одній з колонок. Пошук так само проводиться по колонці, в якій встановлений маркер. Це все залишилося без змін. Однак, якщо почати вводити текст (в прикладі - номер рахунку), то відбудеться наступне.

сайт_

Як бачите, просто автоматично відкрилося вікно пошуку. Таке ж точно вікно відкриється, якщо натиснути на кнопку пошуку на панелі інструментів вікна (на малюнку підкреслена). В результаті при натисканні у вікні пошуку кнопки Знайти (на зображенні прихована за випадає меню) або просто Enter, то вийти наступний результат.

сайт_

Звідси видно, що швидкий пошук в 1С Бухгалтерія 8.3 просто залишає видимої частини списку, що задовольняє умовам пошуку. При цьому кнопка Знайти пропадає, а замість неї з'являється лінза з хрестиком (на рис. Підкреслена), при натисканні на яку список повертається в початковий стан (При цьому залишається виділений рядок, знайдена в результаті швидкого пошуку).

Ще одна важлива особливість швидкого пошуку в 1С Бухгалтерія 8.3 - збіг шукається не по початку рядка, як у версії 8.2, а виробляється пошук на збіг з будь-якою частиною рядків в колонці. Таким чином, якщо контрагента назвати "ТОВ ІмяФірми", а при пошуку почати вводити "ІмяФірми ТОВ", то рядок все одно знайдеться!

робимо висновки

Таким чином, швидкий пошук в 1С Бухгалтерія 8.2 та більш ранніх версіях призначається для прокрутки списку до потрібної рядку, а в 1С Бухгалтерія 8.3 швидкий пошук працює як звичайний фільтр, приховуючи непотрібну вам частину списку.

Головна Нотатки із Задзеркалля

07.02.2013 Пошук по рядку

Реалізовано в версії 8.3.3.641.

Ми серйозно поліпшили введення по рядку. Для цього нам довелося реалізувати новий потужний механізм пошуку в поле введення. Тепер він може швидко працювати за мільйонами записів, що містяться в базі даних.

Ми проаналізували завдання пошуку, що виникають у користувачів. Провели "ревізію" наявних в платформі механізмів, які використовують різні алгоритми пошуку. В результаті введення по рядку придбав якісно нові можливості.

Тепер користувачі можуть шукати в будь-якому місці назви, а не тільки по початку рядка. Вони можуть використовувати при цьому повнотекстовий пошук і навіть виконувати пошук за допомогою фонового завдання. Для того щоб повнотекстовий пошук ефективно працював при введенні по рядку, ми додатково оптимізували цей механізм пошуку і підвищили його продуктивність.

Всі нові властивості, що дозволяють налаштовувати введення по рядку, ми зібрали на окремій закладці вікна редагування об'єкта конфігурації:

Наприклад, ви можете вказати, що пошук буде виконуватися в будь-якому місці рядка, а не тільки в її початку:

Тоді користувач може набирати будь-які фрагменти слів, а не тільки ті символи, з яких починається шукана стрічка:

Використання повнотекстового пошуку при введенні по рядку включається окремим властивістю:

За допомогою повнотекстового пошуку користувачі можуть серед великих обсягів даних швидко знаходити відповідні дані за допомогою одного з слів, що містяться, наприклад, в найменуванні:

Також вони можуть шукати і по кільком відомим словам. Незакінчені слова будуть автоматично доповнюватися можливими поєднаннями:

Якщо обсяг даних великий, то в обох випадках ви можете вказати, що пошук повинен виконуватися за допомогою фонового завдання:

Тоді поруч з полем введення для користувачів буде відображатися анімована картинка, схожа на картинку, яка відображається при фоновому режимі звіту:

  • якщо в об'єкті, який використовується в полі введення, не очікується великої кількості даних, то ми радимо включити пошук рядка в будь-якому місці;
  • якщо в об'єкті планується велика кількість даних, то:
    • ми радимо включити повнотекстовий і фоновий пошук;
    • при цьому ви також можете використовувати пошук рядка в будь-якому місці, але разом з фоновим пошуком і бажано з повнотекстових пошуком; щоб більша частина пошуків виконувалася через повнотекстовий пошук.

Всі перераховані властивості ви можете, при необхідності, перевизначити в процесі виконання прикладного рішення.

На клієнті - в клієнтських обробниках подій поля введення автодобір і ОкончаніеВводаТекста :

На сервері - в модулі менеджера того об'єкта, в даних якого виконується пошук. У обробнику події ОбработкаПолученіяДаннихВибора :

Природно, в цьому місці, на сервері, не можна перевизначити спосіб виконання пошуку "Безпосередньо" або "фоновим завданням" . Тому що виконання коду вже передано на сервер.

Рядок - один з примітивних типів даних в системах 1С: Підприємство 8. Змінні з типом рядок містять текст.

Значення змінних типу рядокполягають в подвійні лапки. кілька змінних даного типу можна складати.

Пер1 \u003d "Слово 1";
Пер2 \u003d "Слово 2";
Пер3 \u003d Пер1 + "" + Пер2;

В підсумку Пер3 матиме значення « Слово 1 Слово 2 ".

Крім того, в системах 1С: Підприємство 8 передбачені функції для роботи з рядками. Розглянемо основні:

ВвестіСтроку (<Строка>, <Подсказка>, <Длина>, <Многострочность>) — функція призначена для виведення діалогового вікна, в якому користувач може вказати значення змінної типу рядок. параметр <Строка> є обов'язковим і містить ім'я змінної, в яку буде записана введений рядок. параметр <Подсказка> необов'язковий - це заголовок діалогового вікна. параметр <Длина> необов'язковий, показує максимальну довжину введеної рядки. За замовчуванням дорівнює нулю, що означає необмежену довжину. параметр <Многострочность> необов'язковий. Визначає режим введення многострочного тексту: Істина - введення багаторядкового тексту з роздільниками рядків; Брехня - введення простий рядки.

Рядок можна ввести і, знаючи код символу в кодуванні Unicode:

символ (<КодСимвола>) — код вводиться у вигляді числа.

Буква \u003d Символ (1103); // Я

Існує і зворотна функція, що дозволяє дізнатися код будь-якого символу.

КодСімвола (<Строка>, <НомерСимвола>) — повертає номер зазначеного символу в кодуванні Unicode у вигляді числа.

Функції перетворення регістру тексту:

ВРег (<Строка>) - перетворює всі символи рядка в верхній регістр.

НРег (<Строка>) - перетворює всі символи рядка в нижній регістр.

Трег (<Строка>) - перетворює всі символи рядка в титульний регістр. Тобто перші літери у всіх словах перетворюється в верхній регістр, а інші літери - в нижній.

Функції пошуку і заміни символів в рядку:

знайти (<Строка>, <ПодстрокаПоиска>) - знаходить номер символу входження підрядка пошуку. наприклад:

Знайти ( "Рядок", "ока"); // 4

СтрНайті (<Строка>, <ПодстрокаПоиска>, <НаправлениеПоиска>, <НачальнаяПозиция>, <НомерВхождения>) - знаходить номер символу входження підрядка пошуку, номер входження вказується у відповідному параметрі. При цьому пошук починається з символу, номер якого вказаний у параметрі НачальнаяПозіція.Пошук можливий з початку або з кінця рядка. наприклад:

Номер4 Входження \u003d СтрНайті ( "Обороноздатність", "О", НаправленіеПоіска. Спочатку, 1, 4); // 7

СтрЗаменіть (<Строка>, <ПодстрокаПоиска>, <ПодстрокаЗамены>) - знаходить в заданій стрічці все входження підрядка пошуку і замінює її на подстроку заміни.

СтрЗаменіть ( "Рядок", "ока", ""); // Стор

Порожня стрічка(<Строка>) - перевіряє рядок на наявність значущих символів. Якщо значущих символів немає, або взагалі ніяких символів немає, то повертається значення істина. В іншому випадку - брехня.

СтрЧіслоВхожденій (<Строка>, <ПодстрокаПоиска>) - обчислює число входжень підрядка пошуку в заданій стрічці.

СтрЧіслоВхожденій ( "Вчитися, вчитися і ще раз вчитися", "Вчитися", ""); // 3

СтрШаблон (<Строка>, <ЗначениеПодстановки1>…<ЗначениеПодстановкиN> — підставляє параметри в рядок за номером. Рядок повинен містити маркери підстановки виду: «% 1 ..% N». Нумерація маркерів починається з 1. Якщо значення параметра Не визначене, Підставляється порожній рядок.

СтрШаблон ( "Параметр 1 \u003d% 1, Параметр 2 \u003d% 2", "1" , "2" ) ; // Параметр 1 \u003d 1, Параметр 2 \u003d 2

Функції перетворення рядків:

Лев (<Строка>, <ЧислоСимволов>) - повертає перші спочатку символи рядка.

прав (<Строка>, <ЧислоСимволов>) - повертає останні символи рядка.

середовищ (<Строка>, <НачальныйНомер>, <ЧислоСимволов>) - повертає рядок довжиною в<ЧислоСимволов>, Починаючи з символу<НачальныйНомер>.

СокрЛ (<Строка>) відсікає незначні символи, які стоять зліва від першого значущого символу в рядку.

СокрП (<Строка>) - відсікає незначні символи, які стоять праворуч від останнього значущого символу в рядку.

СокрЛП (<Строка>) - відсікає незначні символи, які стоять зліва від першого значущого символу в рядку і праворуч від останнього значущого символу в рядку.

СтрПолучітьСтроку (<Строка>, <НомерСтроки>) - отримує рядок многострочной рядки по номеру.

Інші функції:

СтрДліна (<Строка>) - повертає кількість символів в рядку.

СтрЧіслоСтрок (<Строка>) - повертає число рядків в многострочной рядку. Рядок вважається новою, якщо вона відокремлена від попередньої символом переведення рядка.

СтрСравніть (<Строка1>, <Строка2> ) - порівнює два рядки без урахування регістру. Функція працює аналогічно об'єкту СравненіеЗначеній. повертає:

  • 1 - якщо перший рядок більше другий
  • -1 - якщо другий рядок більше першої
  • 0 - якщо рядки рівні

СтрСравніть ( "Перший рядок", "Другий рядок"); // 1

Мене звуть Павло Баркет, я працюю в компанії «Софтпоінт». Ми вже більше 10 років займаємося вирішенням завдань оптимізації продуктивності. І незважаючи на велику кількість вирішених завдань, їх кількість не зменшується, а зростає в геометричній прогресії. Обсяги даних збільшуються, і завдання по оптимізації роботи з цими даними ускладнюються. Цей процес неминучий.

Тема статті - нетривіальні підходи до оптимізації. будуть розглянуті два аспекти:

  • перший - пошук по підрядку. Користувачі часто його використовують, і багато хто, напевно, вже стикалися із значним очікуванням, пошук по підрядку виконується недостатньо швидко.
  • другий - проведення великих документів, Таких, як закриття місяця, розрахунок собівартості. Напевно багато хто стикався з тим, що бухгалтери проводять ці документи по 5-9 годин, вночі і в неробочий час. Найцікавіше, що класичні методи оптимізації тут не завжди допомагають. Якщо ви при проведенні таких документів запустіть в отладчике завмер продуктивності, то побачите, що найбільша кількість часу витрачається на запис в тимчасові або реальні структури - таблиці, регістри і т.д. І вирішити цю задачу класичними методами не виходить.

Пошук по підрядку

Перша тема - пошук по підрядку. За цей рік я стикався кілька разів з проблемами по цій операції. Приходиш в страхову компанію з проханням продовжити цей поліса, тебе пропонують знайти за номером телефону. Зрозуміло, що це не класичний пошук за повним номером телефону, тому що користувач міг завести номер через вісімку, через сімку або ще якось, отже, шукають за фрагментами номера. При цьому використовуються довготривалі операції пошуку - в ряді ситуацій затримка може бути кілька секунд, а може доходити і до хвилин.

Пошук за початковими символам

Почну з першого прикладу, коли пошук здійснюється за початковими символам. Це - окремий випадок пошуку по підрядку, коли користувач точно знає, що шукане значення починається з певних символів.

Пошук за початковими символам реалізується в 1С за допомогою команди ПОДІБНО (Або в англійському варіанті, LIKE) із зазначенням значення з «%» в кінці ( «%» позначає послідовність будь-яких інших символів). Наприклад, ми шукаємо:

Найменування ПОДІБНО "івано%"

Зверніть увагу, що якщо у вас в системі існує індекс по цьому полю, то в SQL-запиті для цього пошуку буде використовуватися Index Seek - це пошук за індексом.

Умова «ПОДІБНО пошуковому рядку» еквівалентно пошуку в діапазоні значень. В окремому випадку, коли ми шукаємо «івано%» - це еквівалентно пошуку в діапазоні прізвищ, які починаються на «івано», і, закінчуючи «іванп» (тому що символ «п» йде після символу «о»).

Сучасні оптимізатори самостійно перетворять запит LIKE на запит пошуку по діапазону. Отже, якщо у вас в системі існує індекс по цьому полю, ви при інтерпретації запиту в терміни SQL отримаєте саме такий результат - оптимізатор представить запит з LIKE у вигляді пошуку по діапазону.

Таким чином, можна здійснювати класичний швидкий пошук з використанням індексу (Index Seek). З цим проблем немає або вирішити їх можна простим способом.

Пошук по входженню

Тепер візьмемо приклад складніше, коли невідомо, в якому саме місці рядка стоїть наше шукане значення, і реалізується пошук по входженню рядки. В цьому випадку в запиті «ПОДІБНО» «%» варто з двох сторін.

При перетворенні такого запиту в SQL ми бачимо, що змінюється тільки команда (в значенні використовується вже два «%»).

Розглянемо докладніше план виконання. тут ми бачимо той же Index Seek, але в даному випадку він не працює ефективно.

Справа в тому, що індекс по найменуванню довідника, який ми розглядаємо, складається з декількох полів.

  • Перше з них - це роздільник обліку.
  • Далі безпосередньо йде поле пошуку.

І тому, коли в плані виконання відображається «Index Seek», це означає, що пошук робиться по першому полю роздільник - на слайді вище можна побачити, що пошук по нашому згаданої значенням Desc абсолютно не використовується.

Що робити в цій ситуації? У мене на практиці було дуже часто, що користувачам забороняли використовувати запити на входження. І користувачі в ряді випадку самі не використали цей функціонал, тому що час виконання дуже значне, а треба продовжувати працювати. Тому їм доводилося викручуватися іншими способами - вибирали в списках, намагалися знайти по перших символах і так далі.

Але це призводить до невдоволення функціоналом і неправильного сприйняття системи. Користувач розуміє, що система з чимось не може впоратися і не працює як належить. Це не правильно.

Нетривіальний підхід до вирішення завдання пошуку по підрядку

Давайте тепер розглянемо нетривіальний підхід до вирішення цього завдання.

Позначимо ряд допусків:

  • Перше - оскільки сучасні диски мають необмежений розмір, Припустимо, що простір на диску, яке ви можете використовувати, у вас є достатньо велика.
  • Друге - користувач шукає не по одному-двом символам, а по якомусь фрагменту. Наприклад, ніхто з нас не шукає по «ал» - це занадто маленька селективність. Шукають якусь значиму послідовність символів. Тут ми для прикладу вибрали пошук по шести символів.

Приклад шуканої рядка «Алекс» записали в форму і будемо з її допомогою тестувати.

  • Припустимо, у нас є поле з прізвищем, ім'ям та по батькові клієнта. Першим кроком ми автоматично розкладаємо це значення на фрагменти з шести символів зі зрушенням «1»і отримуємо масив фрагментів (див. вище), які одночасно завжди належать згаданої значенням. Ми отримали фрагменти, які теоретично може вводити користувач. А саме, на минулому слайді визначили, що ми шукаємо шість символів. Їх може бути і п'ять, і чотири, просто розмір структури буде більше.

  • На другому кроці ми записуємо ці набори в окрему структуру (Це може бути таблиця, регістр відомостей і т.д.) і отримуємо вибірку, в якій певний фрагмент належить різним значенням.

  • І на третьому кроці, ми при пошуку по підрядку до конструкції запиту 1С «ПОДІБНО» додаємо додаткову умову «І», яке фільтрує кількість можливих комбінацій, і витягуємо з цієї додаткової структури (це може бути регістр відомостей) всі елементи, яким належать потрібні фрагменти рядків.

Наприклад, користувач шукає клієнта з прізвищем «Солдатов». Це - вісім символів, значить, буде три фрагмента довжиною в шість символів, які ми шукаємо в службовій структурі. Далі об'єднуємо це все в запиті. Таким чином, виходить додаткова фільтрація.

В результаті ми позбавляємося від знака «%» (тобто попереду цих фрагментів завжди буде потрібний нам символ), і при виконанні внутрішнього запиту буде йти Index Seek, за який ми і боролися.

На практиці виходить дуже цікава історія - прискорення в десятки, в сотні разів. Причому, все це можна зробити засобами 1С, що дуже приємно. Переписувати логіку не буде потрібно, користувач буде радіти, що у нього прискорився запит пошуку. У прикладі прискорення з 4 секунд до 0,05 секунди, а якби у нас спочатку запит виконувався дві хвилини, він став би виконуватися менше секунди.

Механізм, що я вам показав, не є якимось експериментальним прикладом, це вже працює у реальних клієнтів.

Підготовчі заходи для впровадження

Тепер я розповім коротко про підготовчі заходи.

  • спочатку необхідно заповнити реєстр початковими значеннями. Для цього ми повинні запланувати регламентне вікно.
  • Далі ми повинні дотримати консистентность даних - це значить, повинна бути підписка на зміну значення, Щоб ця Фрагменти автоматично перебудовувалися.
  • І останнє - дописати стандартну форму пошуку.

Заповнення реєстру можна робити як засобами 1С, так і за допомогою SQL.

Можу сказати, що заповнення такої структури для 17-ти мільйонів значень займає десь 20-25 хвилин. Природно, користувачі в цей момент не повинні змінювати значення довідника.

Якщо ми розрахуємо для одного мільйона значень десь 100 символів по 6 у фрагменті, вийде десь 4,7 Гб. Потрібно запланувати, щоб це місце у вас було. Якщо у вас в довіднику, наприклад, 100 мільйонів значень, то ви повинні запланувати місце, яке буде доступно на диску.

Необхідність обліку статистики популярності фрагментів

Чи завжди цей метод буде працювати швидко?

На це впливає статистика популярності фрагментів.

  • Наприклад, у вас є фрагмент «Алекс», який може входити в ім'я Олексій, в батькові Олексійович, в прізвище Алексєєнко і т.д. Цей фрагмент може входити в 50-100 тисяч записів.
  • А є рідко використовуються фрагменти.

Таким чином, з'являється статистика популярності за фрагментами.

Зверніть увагу, що якщо популярність фрагментів низька (100 елементів), то ми отримуємо прискорення - 0,1 секунду.

Якщо підрядок досить популярна (50 тисяч елементів), то ми отримуємо деградацію, Причому набагато більшу, ніж якби не було оптимізації.

Таким чином, необхідно зробити поліпшену схему виконання запиту, В якій ми спочатку б отримали значення популярності підзапиту. Це робиться трьома-п'ятьма рядками в 1С. При цьому ми точно знаємо, що якщо рядок непопулярна, то йде по першій гілці, а якщо популярна, то по другий.

Як працює прискорення? Йде запит пошуку з форми, далі ми звертаємося до регістру відомостей зі статистикою, отримуємо елемент і далі вибираємо, що використовувати - класичний або прискорений запит.

А тепер давайте розглянемо, як виконується SQL-запит на SQL-сервері.

На слайді представлена \u200b\u200bспрощена схема:

  • йде запит до оптимізатора;
  • ми дивимося статистику по полях, які використовуються в запиті;
  • вибираємо, який план виконання використовувати, тобто вибираємо стратегію виконання запиту (наприклад, вкладений цикл).

На що схожа реалізована нами схема?

  • Ми зробили свій індекс. Чи не стандартний індекс SQL, що не індекс 1С, а свій індекс, який потрібен для вирішення цього завдання;
  • Більш того, зіткнулися з тим, що потрібна своя статистика;
  • І потрібен власний оптимізатор, Який за цією статистикою вирішує, яку гілку вибрати.

Виходячи з цієї логіки, можна сказати, що цей процес розкриває сенс того, для чого нам індекси, статистика і оптимізатор.

Хто не знав, для чого потрібно обслуговувати статистику в SQL, загляньте в цю логіку, і ви зрозумієте, що якщо вона неправильна або неактуальна, то ми підемо по неправильній гілці. Запит буде гальмувати. Розуміємо, для чого якісно і правильно обслуговувати статистику - це впливає на продуктивність, на індекс.

Якщо індексу немає - будемо сканувати все значення.

Таким чином, ми створили хоч примітивний, але свій оптимізатор. Можна сказати, що промацали «на пальцях» то, як це робить MS SQL та інші СУБД, причому створивши свої структури.

Прискорення «великих» документів

Перейду до другої темі - прискорення великих документів.

Ми в виробничих завданнях часто стикаємося з якимись регламентними процедурами, як: закриття місяця, звіт агенту, розрахунок собівартості. Ці важкі, масивні документи проводяться і заповнюються значну кількість часу. А коли ми заглядаємо в відладчик і робимо на цих операціях трасування, то бачимо, що 1С через підрядник вставляє значення в якусь таблицю і на це йде основний час. І нічого з цим поробити не можна. Єдина рекомендація, яку можна запропонувати - це прискорити диск (ефективність цього рішення дуже сумнівна і вимагає попереднього аналізу).

Пропоную повернутися в історію і розглянути, як це робилося в 1С, починаючи з 8.0 до 8.3 - це робилося через підрядник. SQL-сервер кожен раз аналізував запит, його обробляв, створював план виконання, додавав, відправляв команду в сторону 1С про успішність і отримував наступний запит. І такими step by step йшли запити від 1С сервера додатки до MS SQL.

Зрозуміло, що якщо у вас 40 записів в документі, то проблем виникнути не повинно. Якщо записів у вас стає 10 тисяч і більше (бувають організації, де в регламентних документах мільйон записів), то цей процес займає дуже тривалий час. Одна запис обробляється дуже швидко, але в документі їх занадто багато. На що йдуть накладні витрати? На мережу, на виконання запиту, на зворотний сигнал, на обробку цього сигналу в системі 1С - разом, сума чотирьох етапів. Всі етапи підсумовуються, множаться на мільйон рядків, і виходять наші тривалі очікування. Зрозуміло, що це не страшно.

В 1С, починаючи з 8.3, зроблені поліпшення. Тепер запит для вставки в тимчасові таблиці і в регістри відомостей готується на SQL-сервері, і його подальше виконання відбувається за допомогою класичних RPC-викликів, де сам провайдер доступу 1С (Native або OLE DB) групує записи і вставляє їх по N рядків (як правило 100 рядків).

Таким чином, досягається прискорення від 30% до 300%. Але це все одно недостатньо, тому що сьогодні у вас 10 тисяч рядків, завтра 20 тисяч рядків. Це не принципове рішення проблеми, ви все одно з нею зіткнетеся, але тільки через півроку / рік.

яка найбільш швидка вставка в SQL-сервер, та й взагалі в будь-яку СУБД?

це BULK INSERT. В 1С BULK INSERT використовується, але для інших завдань. Роботу з «великими» документами також хотілося б прискорити шляхом укрупнення вставок INSERT і додавання записів єдиним масивом в базу даних SQL-сервера.

Подивимося, який досягається ефект. У розглянутому прикладі отримано прискорення десь в 5 разів, але можна прискоритися і в 10 разів. Теоретично основна проблема для того, щоб це прискорювалося значно сильніше - це швидкість диска. Диск може є вузьким місцем.

також важливо пам'ятати про такий критерій, як індекси. Якби ми вставляли BULK INSERT в таблицю без поновлення індексів, то ми б отримали значне прискорення (результат менш ніж за секунду). Тут ми отримуємо 69 \u200b\u200bсекунд за рахунок того, що кожна вставка в таблицю вимагає REFRESH індексу.

У будь-якому випадку, цей спосіб дозволяє досягти ефекту в 5-10 разів.

Плюс тут не розглядаються такі можливості, як партіціонірованіе, секціонування. Можна було б поліпшити ситуацію, якби ми знали, що BULK INSERT вставляється в актуальний період, а неактуальне ми винесли б в іншу партіціі. Це був би ще більший ефект. Виходить, що прискорення дуже гарне.

Можливості оптимізації безмежні

Таким чином, можливості оптимізації безмежні. Єдине - не захоплюватися. До оптимізації завжди має сенс порахувати, чи буде передбачуваний ефект чи ні. Також я б радив в якихось ситуаціях «підніматися» над проблемою, використовувати не класичні методи оптимізації запиту, а якісь зовсім інші, які можуть принести більший результат.

****************

Дана стаття написана за підсумками доповіді (), прочитаного на конференції INFOSTART EVENT 2017 COMMUNITY.