<?php // Полная загрузка сервисных книжек, создан 2025-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='\
Подсказать не могу, но однозначно плюс за сборку всего в 1 месте!
Тебе сюда:
http://www.sql.ru/forum
Но там народ слишком манерный(профессиональный) — разжевывать не будут. Что-то на молекулярном уровне подскажут, а концептуально и академически прокачивайся сам.
Начинающим можно посоветовать использовать Maintenance Plans…
(3) Maintenance Plans — вещь в данном случае неподходящая
(2) вот-вот….я в зависать ещё в одном форуме… мне пока хватает тут (:
Череват тормозами базы на время перестройки индекса
Для какой-то оценки проделанной вами работы неплохо привести статистику: размер базы, размер соответствующих таблиц и индексов, время выполнения запроса до и после скрипта, скорость деградации производительности в течении 3 часов между запусками скриптов. Кроме того неплохо знать конфигурацию сервера и конфигурацию 1С.
ПС. А какой смысл очистки кэша каждые 3 часа?
Вы понимаете что этой операцией вы удаляете скомпилированные запросы?
(6) Да… Понимаю, что очисткой кэша удаляю скомпилированные запросы. Но очистку кэша рекомендуют делать после обновления статистики. Практика показывает, что иногда достаточно только очистки кэша, чтобы скорость записи в регистр увеличилась.
Размер базы 100 гБ.
Деградация производительности… Снижение скорости оперативного проведения по регистру партии товаров на складах с 3-4 секунд до 60-90 секунд. Снижение скорости проведение по регистру партии товаров на складах в документах более 3-4 дней с 5-6 секунд до 500 и более секунд. При этом фрагментация индексов регистра партии товаров на складах не превышает 5 процентов…
Платформа 1с 8.2.11.236 Конфа УПП 1.3 Win 2003 x64 SQL 2005 x64. 2 четырех ядерных XEON по 2ghz, 16 Гб оперативы на IBM серваке…. Но… Эти же самые затыки наблюдались на всех версиях 8.1 и УПП 1.2. На 32х битной оси и SQL 2000.
(7) ИМХО проблемы у вас не в фрагментации индексов, а в большом количестве приходов, в результате чего Скуль считает более эффективным сканирование таблиц, чем использование индексов. Тут надо смотреть план запроса и сам тормозной запрос, возможно его легче переделать, чем каждый раз «греметь винтами», кста, а дисковую систему почему сокрыли???
(8) и как бы в 1с этого не учли? По-моему, тут больше проблема в том, что постоянно исправляют документы за прошлые числа (не будет развивать тему запрета изменений задним числом и т.д. — 1с тупо не учел специфику РЕАЛЬНОЙ работы и не сделал удобного механизма альтернативного неоперативному исправлению и перепроведения документов).
Согласен, что нужно анализировать запросы на уровне SQL. Только опыта в этом никакого. Да и после этого не совсем понятно, что делать.
(8) Пока я вижу практический результат от реиндексации, обновления статистики и очистки кэша — устранения провала в производительности. Может попробовать только обновление статистики?
По дискам — tempdb, log и сама база данных разнесены на физически разные диски…
Думаете проблема может быть во фрагментации? На диске с базой ничего другого нет.
(9) А вы считаете что в 1С всЁ учитывают 😉
А когда через год база будет 200Гб — каждый час реиндексировать(дефрагментировать) базу???
Проблема здесь в том что производительность в v8 надо рассматривать в рамках всей системы, т.е. аппаратная платформа+сервер БД+Сервер приложений+платформа 1С.
Базы размером более 50Г уже можно считать большими и настройка таких баз должна выполнятся индивидуально. Возьмите к примеру файловые БД — у них очень хорошая производительность для объемов до 1-2Гб в однопользовательском режиме, а с некоторого объема уже начинаются приколы.
Я не считаю что ваш путь не правильный. Но, может стоит начать разбираться с индексами и статистикой? Это даст гораздо больший выиграш в скорости и масштабируемости. При этом все те регламенты, которые предусмотрены в сервере БД никто не отменял.
Если много INSERT/UPDATE/DELETE в базе, то статистика очень быстро устаревает(характерно для OLTP баз) ее нужно обновлять периодически.
А вы знаете, что обновление статистики выполняется сервером автоматически для некоторых индексов, а для некоторых автообновление отключено. Проверьте включено-ли автообновление статистики примерно так:
DBCC SHOW_STATISTICS (N’dbo._acc1′, _Acc1_ByCode_SR)
или так:
EXEC sp_autostats ‘dbo._acc1’
Смысл параметров я думаю понятен.
Еще есть синхронное и асинхронное обновление статистик.
Статистика очень тонкий инструмент в сервере SQL. Теперь я думаю понятно почему большинство скриптов которые вы нашли не обновляет статистики.
(10) Диски разные, но это могут быть RAID[0,1,5,6,10]? Нужное подчеркнуть.
Монитор производительности — очередь записи на диск, например???
объем оперативы = Объем базы/4, ИМХО конечно.
(11) зачем всю? В том то и дело, что провал в производительности происходит только для 1 конкретного регистра…
(11) а в остальном буду копать дальше
(11) уточняю… automatically recompute statistics в параметрах индекса — это и есть автообновление статистики для конкретного индекса? Если да, то они были включены. Сейчас для пробы я их отключил и оставил только скрипт по перестройке этих конкретных индексов с цикличностью в час.
(14) Да. Но зачем отключать? Для экспериментов? И каковы результаты?
(15) так как знания мои малы — прибегаю к шаманству (: Уже по результатам отключения можно сделать предположение. Автообновление статистики вещь хорошая, но при определенных условиях статистика может формироваться неверная, что приводит к резкому увеличению времени записи в регистр. А чем чаще обновлять статистику — тем больше вероятность, что это произойдет.
Сейчас периодичность обновления статистики — 3 часа. Полет нормальный.
(16) А можно текст задания, который обновляет статистику на всеобщее рассмотрение?
(17) если я правильно все понял, то после перестройки индексов статистики обновляется в любом случае. Поэтому использую скрипт, который идет последний в статье. На данный момент перешел на исполнение этого скрипта раз в сутки + 1-2 раза в день вручную, если начинаются затыки.
(18) Однозначно после ALTER INDEX статистика будет обновлена, но только если включено автообновление, а оно у вас похоже включено.
А какие размеры имеют индексы и таблицы и сколько времени это занимает?
Какая утилизация ресурсов?
Я это к тому, что может допустимый вариант решения: ночью реиндексация, а в течении дня обновление статистики несколько раз.
уже проскакивало :
«общее
— Обновление статистики — каждые 2 часа
— DBCC FREEPROCCACHE — каждые 2 часа»
только вот общее — это для всех баз включая системные или только пользовательские?
(20) всю статистику обновлять — это долго. очистку кэша — можно. Перестраивать несколько индексов и обновлять по ним статистику с очисткой кэша — вот всё, что нужно. У меня это происходит сейчас 3 раза в день. Занимает меньше 2 минут — результат поразительный.
На другой базе иногда вручную делаю очистку кэша. Для чего? У меня есть проверка, которая делате много-много мелких запросов. Иногда один этот запрос начинает выполнятся больше секунды — запрос должен выполнится больше сотни тысяч раз. Такая производительность не устраивает. Очистка кэша (иногда не с первого раза) снижает время выполнения до приемлемых 0,08-0,04 сек в зависимости от близости к текущей дате по времени.
А для SQL 2008 можно применять без изменений?