Заметочки про 1С:Предприятие 8 (редакция 22.06.2012)




Принцип обмена данными из 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='\

99 Comments

  1. Evg-Lylyk
    Так программный код выполняется значительно быстрее. Всё дело в переходах между командами.

    И на сколько быстрее? (примерчик)

    Reply
  2. alexk-is

    (1) Количество повторов 1000000

    Замер код записан в 4 строки. Завершено за 3,329 сек.

    Замер код записан в 1 строку. Завершено за 0,5 сек.

    У меня получилось приблизительно в 6 раз. Но здесь нужно учитывать только время переходов. Если в цикле будут команды, которые выполняются медленно, то и результаты будут иными.

    Reply
  3. alexk-is

    (1) Добавил Тест 1

    Reply
  4. awa

    (1)(2) Я думаю, что разница будет только в режиме отладки. В обычном режиме разницы быть не должно.

    Reply
  5. Diversus
    Для каждого СтрокаТЗ Из Таблица1 Цикл ЗаполнитьЗначенияСвойств(Таблица2.Добавить(), СтрокаТЗ) КонецЦикла;

    А вот так работает, медленней?

    Таблица2 = Таблица1.Скопировать();

    Или я чего то не понял?

    Reply
  6. alexk-is

    (4) Эх… раскусил… Да, действительно был включен режим отладки. Переделал тест. Теперь результат такой.

    Замер код записан в 6 строк. Завершено за 1,532 сек.

    Замер код записан в 1 строку. Завершено за 0,859 сек.

    Почти в 2 раза. Тоже не плохо.

    Reply
  7. alexk-is

    (5) Я имел ввиду вариант Таблица = Таблица1 + Таблица2 + Таблица3 + … ТаблицаN

    Reply
  8. e.kogan

    Вот за заход с итоговыми полями в запросе большое спасибо, раньше не встречала.

    Reply
  9. alexk-is

    (8) Почему не встречала? В http://www.infostart.ru/public/69707/ встречается 4 раза, а эта публикация висит на главной уже больше месяца.

    Посмотри её. Там ещё много вкусного 🙂

    Reply
  10. e.kogan

    (9) Потому что туда в код не залезала, времени не было.

    Reply
  11. alexk-is

    (8) Ну, хоть кого-то удивил.

    Reply
  12. alexk-is

    (4) Приложенный тест убедил?

    Reply
  13. anig99

    хммммм…очень похоже всё-таки на баг компилятора…Скорость работы программы НЕ ДОЛЖНА зависеть от таких вещей…

    Reply
  14. ildarovich

    С результатами согласен

    Функция ТочноеВремя()
    
    Script = Новый COMОбъект(«MSScriptControl.ScriptControl»);
    Script.Language = «javascript»;
    Возврат Script.eval(«new Date().getTime()»);
    
    КонецФункции
    
    Процедура КнопкаСформироватьНажатие(Кнопка)
    
    Старт = ТочноеВремя();
    
    А = 0;
    Для Сч = 1 По 1000000 Цикл
    А = А + 1;
    КонецЦикла;
    
    Сообщить(«В несколько строк:» + (ТочноеВремя() — Старт) + » мск»);
    
    Старт = ТочноеВремя();
    
    А = 0;Для Сч = 1 По 1000000 Цикл А = А + 1;КонецЦикла;
    
    Сообщить(«В одну строку:» + (ТочноеВремя() — Старт) + » мск»);
    
    КонецПроцедуры

    Показать

    Результат(вне отладки):

    В несколько строк:1 531 мск

    В одну строку:1 078 мск

    Но я бы объяснил это не лишними повторениями или переходами между командами, а наличием возможных точек останова и возможностью указания строки ошибки.

    Reply
  15. alexk-is

    (14) Не вижу принципиальной разницы. Давай назовем так — Переход между командами с созданием возможных точек останова и возможностью указания строки ошибки. Результаты тестов от этого не изменятся.

    Reply
  16. awa

    (12)(15) Да, убедил. Это действительно сказываются дополнительные коды (1) в компилированном коде, которые означают номер строки для отладки. В 1С, в отличие от нормальных сред программирования (типа Visual Studio или Embarcadero RAD) нет разделения на режимы компиляции Debug и Release. В 1С, по сути, всегда режим Debug. Ради интереса я перенес тест из формы в модуль обработки, поставил на нее пароль, и обфусцировал ее. Обфускация, кроме всего прочего, выкидывает отладочные коды (1). И результаты сразу стали одинаковыми! Правда, чуть больше, чем не для обфусцированных — вместо 1 сек для 1 строки и 1,4 сек для 6 строк стало по 2 сек. для обоих вариантов, что вполне объяснимо — обфускация добавляет лишние переходы и прочие запутывающие коды.

    Но, по большому счету, и раньше было известно, что 1С для всяких сильно вычислительных и переборных задач совсем не подходит. В реальной же жизни, как правило, скорость работы 1С упирается в скорость работы с БД, и на этом фоне оптимизация просто кода 1С приносит практически незаметные результаты.

    Reply
  17. alexk-is

    (16) Не совсем так. После получения данных из базы наступает момент, когда её необходимо показать пользователю. Вот тут-то и наступает самый интересный момент. Сколько будет стоить поднять производительнось пользовательского ПК, например, на 20% ? А тут халява 🙂

    Reply
  18. Abadonna

    Что-то мне кажется, что говорить в контексте 1С «скомпилированный» не совсем корректно. 1С таки интерпретатор, имхо.

    Reply
  19. awa

    (18) На самом деле 1С и компилятор и интерпретатор одновременно. Исходный код компилируется в промежуточный «п-код» либо в момент первого обращения к модулю, если исходный текст модуля открыт, либо заранее, если исходный текст модуля запаролен или исходный текст модуля отсутствует. Далее полученный «п-код» выполняется виртуальной машиной 1С в режиме интерпретатора.

    Правда, не знаю, как выполняется клиентский код в тонком и веб-клиентах 8.2.

    (17) Ну давай посчитаем. В твоем тесте цикл выполняется миллион раз, в варианте шести строк внутри цикла 4 строки, т.е. за время выполнения теста происходит обработка отладочного кода (1) четыре миллиона раз. Именно этих четырех миллионов вызвовов команды (1) нет в варианте с одной строкой. Уходит на это примерно пол-секунды (на моем рабочем компе разница между тестами 0.4 секунды). В обычной жизни для вывода пользователю результатов запроса из БД надо выполнить не более нескольких тысяч строк (с учетом всех циклов), что на три порядка меньше, чем в тесте. Т.е. способом «пишем всю программу в одну строку» ты будешь ловить миллисекунды.

    Я отнюдь не отрицаю, что эффект есть, я просто говорю, что, как правило, он совсем не стоит внимания. Возможно, в исключительных случаях, и бывает, что таким способом можно получить хоть немного заметную экономию времени. Но скорее всего, это тяжелые алгоритмические или переборные задачи, которые, в таком уж случае, гораздо эффективнее писать на других, компилируемых, языках. С++, например. Выигрыш по времени выполнения чисто алгоритмической программы на С++ по сравнению с 1С может достигать нескольких тысяч раз.

    Reply
  20. anig99

    а если запоролить обработку?

    Reply
  21. WKBAPKA

    а про циклы мне не совсем понятно… вернее понятно 😮 , но почему так?

    Reply
  22. WKBAPKA

    2(13): вот и я о том подумал, на самом деле, одна строка или 6 строк, машине (компилятору) по барабану, для нее на вход поступает линейный поток символов (включая управляющие символы). И какая тут разница, сколько строк или пробелов? Это разве что, время разбора лексем увеличивается за счет работы со строками, типа, чем больше пробелов и прочих не значащих символов, тем больше время разбора, но что бы в два раза!!!

    Reply
  23. WKBAPKA

    прочитал последние посты, вопросы отпали… 🙂

    Reply
  24. anig99

    (19) к тому же множество выкладок по оптимизации кода идет в сторону сокращения циклов или полного их устранения за счет запросов/переноса на сервер…

    Reply
  25. awa

    Кстати, в приведенном коде разбора строки с элементами в массив, есть ошибка, а точнее ограничение. Если в элементах разбираемой строки встречается двойная кавычка, то приведенный код упадет. Поэтому перед преобразованием надо добавить

    РазбираемаяСтрока = СтрЗаменить(РазбираемаяСтрока, «»»», «»»»»»);
    Reply
  26. WellMaster

    Иногда встречал простые задачи, которые нельзя ни перенести на сервер, ни реализовать на запросах — все делалось на клиенте.

    Вот мои замеры (10 млн итераций):

    Замер код записан в 6 строк. Завершено за 25,652 сек.

    Замер код записан в 1 строку. Завершено за 14,771 сек.

    11 секунд выигрыша в моем случае — большой плюс.

    Предложенный способ оптимизации действительно отношу к особенностям компилятора/интерпритатора, а не к оптимизации кода в полном смысле этого слова.

    Но все равно плюс автору за статью.

    Reply
  27. alexk-is

    (25) Ни каких ограничений нет. См. пост (25) — там смимаются все ограничения. 🙂

    А если серьезно, то у меня такой способ разбора строк встречается часто. Взял из модуля, где разбираются строки вида ЭлементыФормы.КоманднаяПанель.Кнопки.Подменю.Кнопки.Действие.Подсказка

    Главное ведь сам прицип. Если принцип понятен, то модифицировать команду под разбор, например, строки чисел уже не составит труда.

    (Подсказка: S заменить на N и убрать некоторые кавычки)

    Reply
  28. Ish_2

    1. Почему для построения двухуровневого дерева нельзя обойтись только первой частью запроса ?

    2. Зачем в одной колонке нужно иметь разные типы ?

    3. Не понял текста запроса после «Объединить Все» .

    — Второй запрос будет пустым . зачем это нужно ?

    4.

    «ИТОГИ

    | Организация КАК СтруктураДоговоров,

    | СУММА(Сумма)

    |ПО

    | Организация»);»

    — После опции ИТОГИ употреблена не агрегатная функция , а «Организация» .

    Что это ?

    Reply
  29. Ish_2

    Виноват. Дошло.

    Reply
  30. alexk-is

    (29) Вот пока выложил только скриншот «Пример 3». Как думаешь, это будет интересно?

    В двух словах — там по периодическому регистру сведений КурсыВалют вычисляются периоды действия курсов и ещё ряд показателей, при этом исключаются записи в которых курс установлен такой же как в предыдущей записи.

    Reply
  31. Ish_2

    (31) Пока замечание.

    Оформлял бы запросы с помощью временных таблиц. И надежнее в выполнении и нагляднее. Уж сколько говорено на эту тему …

    И 1с рекомендует обходиться без вложенных запросов.

    Reply
  32. Ish_2

    Кстати , по пред.сообщению . А я получал такие двухуровневые деревья в «лоб», т.е. в цикле прокручивал выборку и заполнял каждую строку дерева. Твой способ ,насколько я понимаю, побыстрее и поизящнее.

    Reply
  33. alexk-is

    (32) Ну, да. Иначе зачем огород городить?

    Reply
  34. alexk-is

    (31) Переделал на пакетный запрос.

    Однако вопрос в (30) был не про «Пример 2», а про «Пример 3».

    Reply
  35. Поручик

    Покажи пример. Интересно. Я так понял, на нём можно построить что-то таблицы изменения задолженности.

    Фичу с контрагентами будет время воткну в конфу.

    Reply
  36. alexk-is

    (35) Изменение задолженности? Разве типовые отчеты этого не показывают? Хотя остатки в разрезе документов можно таким образом развернуть.

    Нет. Я имел ввиду несколько иное представление именно периодических регистров сведений: КурсыВалют, ЦеныНоменклатуры и т.д. Где это может использоваться? Например, здесь http://infostart.ru/public/70802/

    Reply
  37. alexk-is

    Добавил про сворачивание массивов.

    Reply
  38. Ish_2

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

    Дело , конечно, в том , что при соединении по неравенству в первом запросе размер «промежуточной» таблицы запроса резко возрастает.

    Например , получение первой временной таблицы Периоды при помощи кодинга может дать многократный выигрыш по быстродействию .

    Reply
  39. alexk-is

    (38) По оптимизации выборки в нарастающих итогах могу дать ссылочку http://infostart.ru/public/61295/ 🙂

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

    Т.е. для цепочки 0, 0, 1, 1, 1, 0, 0, 0, 1

    должны остаться только 0, 1, 0, 1

    Reply
  40. Шёпот теней

    (38) … неужели … не ужели … НЕужели … неУЖЕЛИ … вотВЕДЬвот …

    Reply
  41. Ish_2

    Второй в пакете запрос я еще не осилил — до твоей «фишки» не дошел.

    Отметив возможное замедление , продолжим «ковырять» первый запрос пакета.

    В нем фильтрация по &Валюта применена дважды , причем один раз в условии соединения. На мой взгляд , эффективнее и понятнее будет следующий запрос для получения временной таблицы «Соединения»

    Выбрать РАЗРЕШЕННЫЕ КурсыВалют.Период

    Поместить Периоды

    из Регистр.КурсыВалют

    Где КурсыВалют.Валюта=&Валюта;

    ВЫБРАТЬ

    Периоды.Период как Период1,

    Максимум (ЕСТЬNULL(Периоды1.Период, Периоды.Период)) КАК Период2

    Поместить Соединения

    Из

    Периоды КАК Периоды

    Левое Соединение Периоды КАК Периоды1

    Периоды.Период > Периоды1.Период

    Сгруппировать по

    Периоды.Период

    Reply
  42. Ish_2

    (40) Да ,Шепот. Применение в запросе соединения по неравенству — «в лоб» ,

    может дать плачевные результаты.

    Reply
  43. Ish_2

    Посмотрел второй запрос.

    Пример 3 хорош лишь как любопытная демонстрация запросной техники , но ни в коем случае не образец решения задачи. Лучше бы явно это указать в теме.

    Действительно , выгрузив таблицу регистра в таблицу значений мы за ОДИН проход получим выходное дерево многократно быстрее.

    Reply
  44. alexk-is

    (41) 🙂

    — Как-то не очень получается…

    — Конечно можно и получше нарисовать. Ну, там в трехмерной проекции…

    — А я бы нарисовал немного в профиль

    — Да потому, что у вас всё в профиль

    © Миссия Клеопатра

    Добавил вариант с оптимизацией. Работает немного побыстрее, но понять, что делается в двенадцати пакетном запросе мне кажется сложнее. 🙂

    Reply
  45. alexk-is

    (43) Там не дерево. Там список.

    Reply
  46. alexk-is

    (41) Хочу скромно поинтересоваться по поводу «Пример 3 с оптимизацией»…

    Ну, как?

    Reply
  47. anig99

    а на том дереве… или плоды познания, или русалка, или вообще кот, который ссыт в тапки…

    Reply
  48. Ish_2

    Хм.. А как у тебя тема обновляется ?

    Скромно поинтересуюсь : а можно посмотреть пример 3 — оба варианта до оптимизации и после.

    Первый запрос не изменился. Во втором поля выборки, два внутренних соединения, Итоги — как были так и остались.

    Reply
  49. Ish_2

    За (46) гони Сашу , он нас с сурьёзного настроя сбивает.

    Reply
  50. alexk-is

    (48) Там ещё 1 файл. Теперь их 5. Должен быть пакет из 12 запросов

    Reply
  51. Ish_2

    Так я то текст темы смотрю ! А ты в файлах .

    Reply
  52. Ish_2

    (50) Скачал .Посмотрел. Мда.. «Он уважать себя заставил» !

    Ты не подумай — я тоже энтузиаст и всё такое…

    Но увидев текст пакета оробел : стоило ли ?

    Reply
  53. alexk-is

    (52) Что нам стоит дом построть — нарисуем будем жить! 🙂

    Ну, так как?

    Reply
  54. Ish_2

    Представляешь , а если бы в языке запросов для

    временных таблиц был возможен UPDATE ?

    Ведь тогда — все эти выкрутасы с соединениеми по неравенству были не нужны !

    Одна команда UPDATE — и всё !

    Reply
  55. Ish_2

    Кхе-кхе … Придется смотреть попристальнее . Вот блин…

    Reply
  56. alexk-is

    (51) «Пример 3» в статью вставить не решился. Не хочу пока народ пугать. В статье пока «Пример 2».

    Reply
  57. Ish_2

    А ты опубликуй этот длиннющий пакет.

    А ниже приведи текст кода в 15-20 строчек решающий эту же задачу , причем в любом варианте быстрее чем запрос.

    И вывод : дескать решайте сами !

    Reply
  58. anig99

    (54) по поводу апдейта для решения проблем с нарастающими итогами говорено давно… Иначе оптимизированный запрос с соединением по неравенству занимает много страниц… Некоторые «гуру» даже разбираться не хотят (:

    На самом такими темпами нужно ждать 1с 8.5 или 9.0, где будет реализована возможность редактирвания ВРЕМЕННЫХ таблиц и что-то типа UPDATE.

    (57) там можно в меньше, чем 15 строчек уложиться…вопрос только в производительности… А производительсноть повышается 3 способами:

    1. Наращивание железа

    2. Оптимизация рутинных операций путем переписывания на assemblere (или другом языке)

    3. Написанием сложного и длинного алгоритма, возможно с применением математических моделей.

    Reply
  59. anig99

    (49) пятница…жарко…вечером ещё ехать на шабашку… дай коту нассать в тапки…

    Reply
  60. Ish_2

    (53) В субботу попробовал твой «Пример № 3»

    Теперь и ты отведай моего гостинца .

    1. Текст запроса сокращен в 1,5 раза.

    2. Быстродействие запроса увеличилось в 1,5 раза

    В прикрепл.файле «Гостинец» твоя обработка «пример № 3» с измененным текстом запроса.

    Reply
  61. alexk-is

    (60) Всё зависит от информационной базы. На SQL разницы не получилось, а вот на файловой «гостинец» на 18% быстрее. Только «гостинец» по первой дате выдает неправильный результат в «Изменение курса». Всё равно спасибо. Буду изучать.

    Reply
  62. Ish_2

    (61) Проверялась в субботу действительно на файловом варианте.

    На небольших объёмах проверять бессмысленно.

    Создай 1 000 — 10 000 различных курсов по одной валюте и сравни результаты.

    выигрыш в быстродействии должен быть никак не меньше 1.5 раза.

    На мой вкус, «Гостинец» в первой строке выдает как раз правильный результат :

    «Изменение курса» в первой строке не имеет смысла , т.к. пред.курс неизвестен.

    Reply
  63. vip

    (61) > Только «гостинец» по первой дате выдает неправильный результат в «Изменение курса».

    Да наплюй ты на результат. Главное, шо 18%.

    Reply
  64. alexk-is

    (63) Дошел до 4 и 5 запросов в пакете — случился взрыв мозга. Иду за кофе…

    Reply
  65. Ish_2

    (64) «Взрыв мозга» , на самом деле, — это мне минус.

    Нужно было оставить комментарии.

    Reply
  66. anig99

    (65)(64) а комментарии — это моя статья про нарастающие итоги (: Как раз разбиение соединений сначала на более крупные периоды, а потом на более мелкие.

    Reply
  67. Ish_2

    (66) Саша, ты не в теме. Совсем.

    Reply
  68. anig99

    (67) думаешь, если тут коты в тапки ссут, то я не в теме? Я посмотрел гостинец из (60)… Разве там не продемонстрировано применение сложного алгоритма для оптимизации времени выполнения запроса?

    Reply
  69. Ish_2

    А пока помечтаем и о другой необходимой возможности в языке запросов 1с :

    указывать в полях выборки запрос . Разумеется , такая возможность давно реализована в диалектах SQL.

    И тогда вместо соединения по неравенству можно следующее, многократно более эффективное :

    Выбрать
    КВ.Период  как ТекущийПериод,
    (Выбрать Первые 1
    КВвнутр.Период из РегистрСведений.КурсыВалют как КВвнутр
    ГДЕ  КВвнутр.Период<КВ.Период
    Упорядочить ПО КВвнутр.Период Убыв) как ПредыдущийПериод
    ИЗ РегистрСведений.КурсыВалют как КВ
    Reply
  70. Ish_2

    (68) Да , это так . Этот подход применил Алексей — я лишь повторил его.

    Дело совсем не в этом .

    Всё крутится вокруг «фишки»( Алексей употребил это слово) в (39).

    Reply
  71. vip

    (69)

    Разумеется , такая возможность давно реализована в диалектах SQL.

    Разумеется.

    И в 1С++ тоже.

    Все чаще ловлю себя на мысли, что с 1С++ (в связке с FormEx, разумеется) не осталось ничего, о чем стоит помечтать.

    Пора, наверное, на восьмерку. Освежить, так сказать, мечтательный раздел мозга.

    Reply
  72. alexk-is

    (60) Загрузил курсы валют за 12 лет. Получил следующие результаты для файловой версии.

    Вариант 3. Обычное соединение. Завершено за ~35,5 сек.

    Вариант 3. Оптимизированное соединение. Завершено за ~12,5 сек.

    Гостинец. Оптимизированное соединение. Завершено за ~12,5 сек.

    Починенный Гостинец. Оптимизированное соединение. Завершено за ~12,5 сек.

    Разница в производительности очень не значительная 🙁

    Reply
  73. Ish_2

    (82) Давай подробнее.

    Рассматривается файловый вариант. Исследуются две обработки

    «Гостинец.epf»

    и «Пример 3_2» , скачанный в текущей теме сегодня в 18-20 мск.

    Количество ежедневных курсов (подряд) с 1998 года по сегодняшний день составило в тестовой базе БП 1.6 — 4400 шт.

    Замер времени исполнения запроса производился средствами ТВОЕЙ обработки.

    Каждая обработка запускалась 3 разF.

    Время выполнения Гостинец.epf — ~ 11.7 сек

    Время выполнения Пример3_2.epf — ~ 17.7 сек

    Выигрыш 1.5 раза.

    Кто нас рассудит ? Помогите , люди добрые !

    Reply
  74. Ish_2

    И вот еще что .

    Алексей , оно ,конечно, дело твоё — имеешь право скрывать чужие комментарии в своей теме. Но комментарии vip’a ты скрыл зря. У меня остался какой-то гаденький привкус.

    Reply
  75. Abadonna

    (102) Закрыл Арчи. Так что к Алексею ты не по адресу 😉

    Ежели честно: там был околотемный флад. Хотя и не такой уж фладистый 😉

    Короче: стандартный спор упертых семерочников со мной широкообразованным ( 😀 ), начиная от 2.0 до 8.2 😉

    Reply
  76. alexk-is

    (101) Так. Был немного занят — делал сыну мечи.

    Итак дома загрузил курсы в БП 1.6 — 8491 запись в регистре сведений Курсы валют по EUR и USD с 01.01.1999

    Время выполнения Гостинец.epf — ~ 12.3 сек

    Время выполнения Пример3_2.epf — ~ 12.6 сек

    Время выполнения Пример3.epf — ~ 35.5 сек

    Reply
  77. vip

    (102) Чтобы не оставалось привкуса, скопировал удаленные посты тебе в личку.

    Как видишь, ничего особенного, кроме отхода от темы ветки, который поддержали кстати и ув. модераторы.

    Приношу автору извинения.

    А мысли мои по поводу 8.2 повторяются здесь http://infostart.ru/public/71438/?PAGEN_1=1#comm

    Reply
  78. Ish_2

    (107) Ага.Спасибо.

    Reply
  79. Ish_2

    Давай уж добьем до конца этот вопрос.

    (68) ,(107) Саша и Артур , просьба :

    Пожалуйста , протестируйте и сравните на предмет быстродействия:

    1. Прикрепленную обработку в (60) Гостинец.epf

    2. В текущей теме в разделе «файлы» четвертый файл «пример с оптимизацией» Пример 3_2.epf.

    Нужно в БП , а потом в УТ создать ежедневные разные курсы по одной валюте за 12 лет и запустить обработки 1 и 2. Сравнить время выполнения .

    Не откажите хорошему человеку. Вы нас рассудите с Алексеем.

    P.s. Было бы хорошо — и для файлового варианта и для клиент-серверного.

    Reply
  80. Ish_2

    +(68),(107) Виноват. Алексей уже успел поменять на новую версию свой «пример3_2» .

    Сравнивать нужно с первоначальным примером.

    Reply
  81. alexk-is

    (123) А не проще из «Гостинец» вырезать 3 строки?

    ИНДЕКСИРОВАТЬ ПО

    Период1,

    Период2

    Reply
  82. Abadonna

    (124) А не проще прекратить быстродействиями меряться? 😀

    Практической пользы — практически ноль. Ну, одна за 17 секунд, другая за 15…

    Ну и фигли? 😉

    Нажал я кнопочку «Загрузить» и пишу этот коммент (а менеджер по асе девочку охмуряет).

    Один фиг загрузит быстрее, чем вышеизложенное 😉

    Reply
  83. alexk-is

    (123) 🙂

    — У меня программа в 2 раза меньше твоей, работает в 10 раз быстрее, имеет изумительное юзабилити.

    — Ну, и что? Зато моя работает правильно.

    А если серьезно, то мне понравилось решение в «Гостинец», иначе не появился бы «Пример3_3».

    Reply
  84. artbear

    (121) Пока некогда тестировать 🙁

    пока только иногда почитываю

    Reply
  85. Ish_2

    (126) Черт возьми ! Возник спор — нужно установить факты.

    После того как факты установлены — делиться размышлизмами и делать выводы .

    Reply
  86. alexk-is

    (128) Как мне кажется, особо спорить не о чем.

    В SQL версии

    «Гостинец» работет немного быстрее как в вариантах с индексами, так и без индексов

    В файловой версии

    При использовании индексов «Гостинец» также быстрее

    «Пример3_3» быстрее без индексов, но это скорее исключение — может дело в базе или в расположении звезд

    Мне, например, гораздо интереснее — почему с индексами в файловой версии работает значительно медленнее чем без индексов.

    Reply
  87. Ish_2

    (129) Точнее всё-таки сформулировать так :

    Почему при ЯВНО заданном индексе для врем.таблице в файловой базе наблюдаются жесткие тормоза ?

    И почему при НЕЯВНО заданном индексе (ведь наверняка его создал оптимизатор запроса) тормозов не наблюдается.

    Reply
  88. artbear

    (130) А на скуле проверяли с индексами и без ?

    Reply
  89. alexk-is

    (131) Лучшее время из 10 тестов. MS SQL 2005. УПП 1.2.

    С индексами

    Время выполнения Гостинец.epf — 0,484 сек

    Время выполнения Пример3_2.epf — 0,469 сек

    Без индексов

    Время выполнения Гостинец.epf — 0,343 сек

    Время выполнения Пример3_2.epf — 0,516 сек

    Reply
  90. Yashazz

    (57) Эстер тоже любит наворотить запрос, листингов на 70, а потом выясняется, что кодом оно решается в 20 строк и быстрее, и прозрачнее. На мой взгляд, запрос ради запроса это уже искусство, а не прагматика, реально же надо искать золотую середину.

    Reply
  91. Ish_2

    (200) Бог с ним , с этим штампом о золотой середине. Кто её видел ?

    Прагматика должна опираться на исходные положения :

    1. Данные хранятся только на сервере.

    2. Любое обращение к данным есть запрос.

    3. Эффективнее преобразовывать данные там , где они хранятся. Без перегонки на клиента.

    4. Переводя решение на SQL -запрос , мы делаем его технологичнее (отвязываемся от слабости клиента).

    Эти исходные положения диктуют совершенно определенный взгляд на решение любой задачи.

    Тошнота от циклов , if-ов , case-ов, рекурсий — нормальная реакция здорового мозга.

    Понятно , что без кодинга совсем не обойтись. НО.

    Корявая попытка написать запрос полезнее двух корректно написанных процедур.

    Долой кодинг ! Даешь прозрачный запрос !

    Reply
  92. hogik

    (201)

    «Переводя решение на SQL -запрос , мы делаем его технологичнее (отвязываемся от слабости клиента).»(с)

    Отвязываясь от «слабости клиента»(с) происходит отвязывание и от мозгов клиента. Если мозгов (алгоритмических возможностей) «запросного» сервера хватает для решения поставленной задачи, то — да. А если не хватает? Упрощаем (извращаем) постановку задачи? Подстраиваем схему БД под средства (запросы) обработки данных? Громоздим «средний уровень»? И всё это ради утверждения «Любое обращение к данным есть запрос»(с). Откажитесь от использования только запросов, и получите «золотую середину»(с). Все так просто… 🙂

    Reply
  93. Ish_2

    (202) Всё как обычно, Владимир ?

    а) Ничего не утверждаем,

    б) ничего не предлагаем

    Но :

    в) спорим

    в) сомневаемся ,

    г) отрицаем ,

    е) отказываемся …

    С одной стороны , имеете право . Так безопаснее , чем лезть на рожон

    с утверждениями и предложениями : не «задолбят».

    С другой стороны , блекло и тускло. Всё как обычно…

    Reply
  94. hogik

    (203)

    Всё как обычно, Игорь ? 🙂

    Я утверждаю, предлагаю, делаю…

    И если Ваш гонор не позволяет понять, даже, мои разработки, то пишите запросы дальше.

    Reply
  95. Ish_2

    (204) Ок. Поговорили.

    Reply
  96. hogik

    (205)

    Игорь.

    Для разговора требуется от собеседников, чтобы они читали не только свои сообщения.

    Или, читая, не заменяли все слова собеседника на слово — «восьмерка». У Вас это не получается…

    Ок.(с) 🙂

    P.S.

    Сделаю еще одну попытку достучаться: http://citforum.ru/database/articles/seltzer/

    Reply
  97. cool.vlad4

    (201) см.133

    Reply
  98. Ish_2

    (211) Спасибо за информацию.

    Reply
  99. HystriX

    (16) Возможно, отсутствие разделения на Debug и Release обусловлено тем, что в 1С есть возможность для удобства помощи пользователям и разбора всяких нестандартных ситуаций прямо в открытом сеансе установить флаг «Отладка в текущем сеансе разрешена» и сразу же подключиться конфигуратором и начать отладку. И эта возможность иногда оправдывает себя намного больше, чем едва ощутимый прирост производительности алгоритмов 🙂

    Reply

Leave a Comment

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