Управление индексами и секциями в 1С




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2024-01-05 12:44:55

global $wpdb2;
global $failure;
global $file_hist;

/////  echo '<H2><b>Старт загрузки</b></H2><br>';

$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
/////   echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}

$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
/////   echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}

/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
/////   echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
/////    echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist);   ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7];    ////получаем размер файла
$m_mtime_file=$masiv_data_file[9];   ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file

/////   echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
/////   echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
/////   echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);

if ($results)
{   foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));

////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
/////   echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
/////   echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}

////загружаем данные
$table='vin_history';         // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация     // (путь от корня web-сервера)
$delim=';';          // Разделитель полей в CSV файле
$enclosed='"';      // Кавычки для содержимого полей
$escaped='\

32 Comments

  1. Magister

    И работает это всё, как всегда, только для MsSQL? Или поддерживаются и другие СУБД?

    Reply
  2. German

    (1) Ну да… поддержка в других СУБД в планах … но уж больно тяжело именно это сделать

    Reply
  3. iov

    (0) Вот еще бы пару ссылок на секционирование и вообще няшно бы было 🙂

    Reply
  4. smielka

    Спасибо очень удобный инструмент!

    Reply
  5. iov

    (3) Пардон http://msdn.microsoft.com/ru-ru/library/ms188706.aspx на андроиде почему то ссылка не подсвечена оказалась.

    Reply
  6. Ish_2

    (0) Ничего не понял.

    Грамотный SQL-щик , скажи мне, простому 1с-нику .

    Мы что , используя твою обработку, устанавливаем ADO-соединение со своей же базой SQL ?

    Затем вводим секции для физических таблиц (меняем характеристики базы)? И что потом ?

    После выгрузки базы в .dt и последующей загрузке — мы потеряем всё секционирование ? Так ?

    Reply
  7. German

    (6) да соединение со своей же базой, или ее копией (главное чтобы структура метаданных была одинаковая)

    конечно dt не сохраняет данную информацию… только бекап средствами SQL

    Reply
  8. Ish_2

    (7) Еще вопрос.

    У меня очень большая таблица (2 млрд записей). Хочу из нее , используя Group by, получить таблицу — 32 записи.

    Мне поможет секционирование ?

    И вопрос ,к теме неотносящийся.

    В принципе возможно в MSSQL параллельно выполнить 32 запроса для получения каждой записи.

    Например , послать 32 запроса :

    select * from table where property = 1;

    select * from table where property = 2;

    ……………………

    select * from table where property = 32;

    ну и затем объединить их ,конечно,в одну.

    Reply
  9. German
    Ish_2 пишет:

    Мне поможет секционирование ?

    Нет тут достаточно только индекса. Если будет отбор тогда поможет.

    ну и затем объединить их ,конечно,в одну.

    Стоимость таких запросов будет высока очень.

    Вот тут посмотри многое разъяснится http://www.sql.ru/articles/mssql/2005/073102PartitionedTablesAndIndexes.shtml#5

    Reply
  10. Ish_2

    (9) Ммм.. Ага, высока не то слово.

    За ссылку спасибо.

    Reply
  11. lustin

    (0) инструментарий действительно выглядит отлично — явно проделана огромная работа.

    Однако вынужден заметить две вещи:

    1. по индексам — практика показывает что необходимости управлять индексами на уровне СУБД нет: 1С в основном создает достаточные индексы. Опять же та же практика показывает что если движок рекомендует создать какие либо индексы, то исправлять это необходимо на стороне 1С. в 99 процентах появление рекомендуемых индексах связано с неверной архитектурой метаданных, неверно составленными запросами 1С, забытыми «галочками» индексировать у реквизитов и измерений и т.д.

    2. с секционированием — по ссылке приведенной в (9) очень четко описан процесс создания, и опять же как показывает практика больше всего времени при секционировании уходит на обоснование и обдумывание: где расположить файловые группы, какую функцию секционирования создать и т.д. А вот когда план секционирования был полностью обдуман (включая план возврата секционирования при реструктуризации таблицы) время затраченное на написание скриптов было ничтожно мало.

    и еще: когда база достигает размеров таких, что требуется задумываться о секционировании, сжатии, и анализа индексов таблиц — необходимо подумывать о выделенном DBA, а эти люди как известно используют SQL Managment Studio и ей им достаточно для выполнения их задач.

    Reply
  12. German

    (11) Конечно инструмент не для DBA, они даже смотреть не будут, мировоззрение совсем другое.

    Скорее для 1С стремящихся в выяснению и осознанию определенных проблем производительности MSSQL

    Reply
  13. Ish_2

    (11) Согласен.

    Узок, чрезвычайно узок круг потребителей продукта.

    В базах до 50-70 Гб ( а это огромное подавляющее большинство , думаю 95% ) 1с-нику знать про секционирование не только ненужно , а даже вредно .

    Reply
  14. lustin

    (0) Но плюс то однозначным, забыл сразу поставить

    (12) Кстати Герман — может попробуешь добавить функциональность поиска запроса вызвавшего рекомендацию о создании индекса, у меня получилось через XPath выражения к планам запросов. Думаю такая функциональность будет полезной для продукта.

    Reply
  15. German

    (14) план запроса и связанные с ним фишки уже на подходе. не переключайтесь

    (13) секции это не всегда следствие огромных баз.. у меня была ситуация когда секционирование применялось для увеличения параллельности работы

    Reply
  16. Mudrii_Gankster

    спасибо за информацию буду изучать эту тему

    Reply
  17. opiumdx

    Спасибо, интересно было посмотреть.

    Reply
  18. Aleskey_K

    Спасибо автору и комментаторам за полезную информацию.

    Reply
  19. B2B

    Интересная тема, не знал, что такое возможно. К автору видео: говорить в микрофон можно и погромче (и поувереннее), либо нормализовывать звуковую дорожку перед выкладыванием видео

    Reply
  20. German

    (19) я там вначале что то «застеснялся», потом веселее становится 🙂

    Reply
  21. Natalex95

    Скачал, решил поэкспериментировать с секционированием, но что то не получается…

    После настройки соединения высвечивается надпись «Свойства объектов доступны только для версии MSSQL 2005 и выше»

    Хотя у меня стоит mssql2008, что я могу делать не так? может существуют какие-то тонкости?

    Версия 1С 8.2.13.205

    Reply
  22. German

    (21) используйте последнюю версию

    http://code.google.com/p/enterprise-integrator/downloads/list

    Reply
  23. Natalex95

    А как купить лицензию, что то с сайта переадресовывает на http://infostart.ru/public/14635/index.php?action=buy&id=79875. Где написано, что цена на продукт не определена, и в корзину не добавляется.

    И вообще интересует вопрос, как это будет выглядеть, по доставке.

    Reply
  24. German

    (23) Ошибка на IS была уже исправили.

    По доставке: после получения IS денег на РС сразу же EMS`ом отправляется ключ (~ 3 дня в Москву 7 по России), стоимость доставки входит в цену Ei. Потом в конце месяца получаете документы от IS. Все.

    Reply
  25. svbel85

    а почему пишет что доступна только для скл 2005, при попытке установки соединения??

    Reply
  26. German

    (26) используйте последнюю версию

    http://code.google.com/p/enterprise-integrator/downloads/list

    Reply
  27. ulili

    Спасибо автору

    Reply
  28. zavedeev

    Спасибо!!!

    Reply
  29. retif

    СпасибО!

    Осталось разобраться как это богатство использовать…

    Reply
  30. zoytsa

    1C при создании наборов записей регистров, подчиненных регистратору,

    при записи документа делается SELECT с отбором по регистратору. Есть ли возможность осуществить «partition elimination» в данном случае — чтобы при чтении таблицы документов использовался только раздел, соответствующий, а не шло чтение всех секций?

    Возможно ли секционирование по регистратору?

    Reply
  31. zoytsa

    Ауу, ребят, кто секционривал большие базы — сталкивались ли с зависаниями при проведении/отмене проведения? Как решали проблему partition elimination — т.к. отбор в запросах SQL идет в данных операциях по регистратору, а не по периоду?

    Reply
  32. German

    (32) zoytsa, с зависаниями не сталкивался.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *