OberonCore https://forum.oberoncore.ru/ |
|
Mysql https://forum.oberoncore.ru/viewtopic.php?f=90&t=2908 |
Страница 2 из 2 |
Автор: | Борис Рюмшин [ Суббота, 21 Июнь, 2014 18:15 ] |
Заголовок сообщения: | Re: Mysql |
Какой-то бред. Операторы через ";" выполняются только для консольного клиента mysql и там являются частью его входного синтаксиса, в том числе и для дампов. ";" не входит в диалект SQL, который поддерживается в MySQL. Так что никакая эта не важная особенность. Это из разряда "а вот мне захотелось фичу прикрутить". |
Автор: | Илья Ермаков [ Суббота, 21 Июнь, 2014 20:56 ] |
Заголовок сообщения: | Re: Mysql |
При чём тут сам язык SQL. Возможность выполнить одним запросом к СУБД несколько запросов SQL - это функциональность биндинга к СУБД. И она предоставляется MysqlAPI, просто не была задействована в подсистеме Mysql. Функциональность очень важная. В режиме отдельной отправки на СУБД каждого INSERT-а с ожиданием ответа (а по-другому не получится взаимодействовать с базой) ты хорошо если 500 запросов в секунду прогонишь. А то и 200. А у меня есть объект "результат измерений". Он содержит N параметров (N от 5 до 15 в зависимости от аппарата). Т.е. для добавления ОДНОГО объекта в базу нужно 6-16 INSERT-ов (т.е. параметры хранятся не поколоночно, а по трём таблицам int_params, real_params, string_params). А если в пакетном режиме добавляется 500 таких результатов измерений (в конце дня пошёл экспорт с аппарата)? Это под 10000 INSERT-ов... |
Автор: | Борис Рюмшин [ Воскресенье, 22 Июнь, 2014 09:50 ] |
Заголовок сообщения: | Re: Mysql |
Это немного. Более того, в одном INSERT можно передвать много записей (VALUES). |
Автор: | Илья Ермаков [ Воскресенье, 22 Июнь, 2014 09:59 ] |
Заголовок сообщения: | Re: Mysql |
VALUES не спасает, если идёт INSERT в одну таблицу, затем несколько ISERTов в разные подчинённые, с использованием в них LAST_INSERT_ID() для связывания с только что добавленной записью в главную. Как это немного, если чисто физически на TCP/IP в режиме "запрос - ожидание ответа - следующий запрос" ты много за секунду не прогонишь из-за латентности (мы же ещё на своих даже протоколах налетали на это, кажется, упирались в порядка нескольких сотен запрос-ответов в секунду). Таким образом, выполнение в индивидуальном режиме 10 тысяч INSERTов затянется на пол-минуты точно. |
Автор: | Борис Рюмшин [ Воскресенье, 22 Июнь, 2014 10:03 ] |
Заголовок сообщения: | Re: Mysql |
Это нормально. Кстати, сделай два варианта и посмотри, сильно ли будет отличается скорость. Нужен эксперимент. |
Автор: | Иван Денисов [ Воскресенье, 22 Июнь, 2014 13:15 ] |
Заголовок сообщения: | Re: Mysql |
Илья Ермаков писал(а): А у меня есть объект "результат измерений". Он содержит N параметров (N от 5 до 15 в зависимости от аппарата). Т.е. для добавления ОДНОГО объекта в базу нужно 6-16 INSERT-ов (т.е. параметры хранятся не поколоночно, а по трём таблицам int_params, real_params, string_params). А если в пакетном режиме добавляется 500 таких результатов измерений (в конце дня пошёл экспорт с аппарата)? Это под 10000 INSERT-ов... Новая функциональность в драйвере это хорошо. Однако, при всем уважении, где-то на этапе проектирования баз данных вы создали себе проблем. Любопытно, зачем же измерение вставлять в кучу таблиц? К тому-же есть бинарные типы данных, если требуется универсальный тип хранить. |
Автор: | Илья Ермаков [ Воскресенье, 22 Июнь, 2014 17:56 ] |
Заголовок сообщения: | Re: Mysql |
На самом деле, мы занимаемся тем, чем занимается любой ORM (Object-Relation Mapper...) Неплохо некоторые идеи описаны у Усова (http://alexus.ru/russian/articles/dbms/oop_rm/index.htm). Контекст проекта: небольшой заказ на сбор данных с трёх медицинских анализаторов. Делают мои студенты, архитектуру-каркас, естественно, пришлось с ними вместе выстроить. Проектировалась не реляционная БД, проектировалась объектная модель - и ровно нужные функции хранения и выборки объектов. А потом уже это проецировалось на реляционку (а можно без изменения приложения реализовать на чём угодно). Я бы охотнее взял NoSQL - Mongo ту же самую (у нас она применяется, но не из ББ). Но ввиду отсутствия драйвера.... Если интересно, выглядит примерно так модель и хранение. Это объектная модель: Код: DEFINITION HemoData; IMPORT Dates; CONST maxParamCount = 64; TYPE PersonalCode = ARRAY 64 OF SHORTCHAR; DateTime = RECORD date: Dates.Date; time: Dates.Time END; Result = POINTER TO LIMITED RECORD (* Result почти неизменен, создаётся и "накачивается" данными однократно - при получении с анализатора, потом отправляется в базу. После считывания из базы возможно только одно изменение - FixPersonalCode. *) readOnly-: BOOLEAN; dbCode-: INTEGER; personalCode-: PersonalCode; analyzerType-: INTEGER; analyzeTime-, registerTime-: DateTime; values-: Value; (r: Result) AddInt (param, x: INTEGER), NEW; (r: Result) AddReal (param: INTEGER; x: REAL), NEW; (r: Result) AddString (param: INTEGER; IN s: ARRAY OF CHAR), NEW; (r: Result) Lock, NEW; (* Переводит объект в режим readOnly, после добавления всех параметров *) (r: Result) FixPersonalCode (IN newCode: ARRAY OF SHORTCHAR), NEW; (* Единственная операция, изменяющая уже существующий в базе результат *) (r: Result) Param (param: INTEGER): Value, NEW END; Value = POINTER TO ABSTRACT RECORD next-: Value; param-: INTEGER END; IntValue = POINTER TO LIMITED RECORD (Value) x-: INTEGER END; RealValue = POINTER TO LIMITED RECORD (Value) x-: REAL END; StringValue = POINTER TO LIMITED RECORD (Value) x-: POINTER TO ARRAY OF CHAR END; VAR nullTime-: DateTime; PROCEDURE NewResult (dbCode: INTEGER; IN personalCode: ARRAY OF SHORTCHAR; analyzerType: INTEGER; IN analyzeTime, registerTime: DateTime): Result; END HemoData. А это хранилище: Код: DEFINITION HemoDB; IMPORT HemoData, Dates, HemoCollections; CONST compareAnalyzeDate = 2; compareAnalyzerType = 1; comparePersonalCode = 0; compareRegisterDate = 3; TYPE Criteria = RECORD compare: SET; personalCode: HemoData.PersonalCode; analyzerType: INTEGER; analyzeDates, registerDates: RECORD from, to: Dates.Date END END; VAR connected-: BOOLEAN; PROCEDURE Connect; PROCEDURE Close; PROCEDURE RegisterResults (results: HemoCollections.Collection); PROCEDURE UpdatePersonalCodes (results: HemoCollections.Collection); PROCEDURE Select (IN criteria: Criteria): HemoCollections.Collection; END HemoDB. База имеет следующий вид: Код: CREATE TABLE results ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL, personalCode VARCHAR(255) NOT NULL, analyzerType INT UNSIGNED NOT NULL, analyzeDate DATE NOT NULL, analyzeTime TIME NOT NULL, registerDate DATE NOT NULL, registerTime TIME NOT NULL ); CREATE TABLE real_values ( result_id INT UNSIGNED NOT NULL, param INT UNSIGNED NOT NULL, value REAL NOT NULL, FOREIGN KEY (result_id) REFERENCES results(id), UNIQUE(result_id, param) ); CREATE TABLE string_values ( result_id INT UNSIGNED NOT NULL, param INT UNSIGNED NOT NULL, value VARCHAR(255) NOT NULL, FOREIGN KEY (result_id) REFERENCES results(id), UNIQUE(result_id, param) ); CREATE TABLE int_values ( result_id INT UNSIGNED NOT NULL, param INT UNSIGNED NOT NULL , value INT UNSIGNED NOT NULL, FOREIGN KEY (result_id) REFERENCES results(id), UNIQUE(result_id, param) ); Плюс, конечно, индексы. Таким образом, при реализации на базе SQL RegisterResults продуцирует последовательность INSERT INTO results ...; INSERT INTO xx_values VALUES (LAST_INSERT_ID())......... Select продуцирует UNION SELECT следующего вида (где условие WHERE приходится трижды помещать в каждый SELECT): Код: SELECT id, personalCode, analyzerType, analyzeDate, analyzeTime, registerDate, registerTime, param, 1 AS param_type, value AS int_value, NULL AS real_value, NULL AS string_value FROM results, int_values WHERE result_id = id " + where +
"UNION SELECT id, personalCode, analyzerType, analyzeDate, analyzeTime, registerDate, registerTime, param, 2 AS param_type, NULL AS int_value, NULL AS real_value, value AS string_value FROM results, string_values WHERE result_id = id " + where + "UNION SELECT id, personalCode, analyzerType, registerDate, registerTime, registerDate, registerTime, param, 3 AS param_type, NULL AS int_value, value AS real_value, NULL AS string_value FROM results, real_values WHERE result_id = id ORDER BY id"; |
Автор: | Илья Ермаков [ Воскресенье, 22 Июнь, 2014 18:15 ] |
Заголовок сообщения: | Re: Mysql |
Ну а теперь убедительный тест преимущества пакетных INSERT. Процедура Insert1000 засунет в базу 1000 объектов (с 5 параметрами каждый, т.е. 6000 INSERT) пакетным запросом. Процедура RegisterBySeparateRequests каждый объект засовывает отдельным обращением к базе (т.е. 1000 запросов к СУБД, в каждом по 6 INSERT). Код: PROCEDURE Register1000*; VAR results: Collections.Collection; res: Data.Result; i: INTEGER; t: LONGINT; BEGIN res := NewResult(); results := Collections.dir.New(); FOR i := 0 TO 1000 DO results.InsertLast(res); END; DB.RegisterResults(results) END Register1000; PROCEDURE RegisterBySeparateRequests*; VAR results: Collections.Collection; res: Data.Result; i: INTEGER; t: LONGINT; BEGIN results := Collections.dir.New(); res := NewResult(); results.InsertLast(res); FOR i := 0 TO 1000 DO DB.RegisterResults(results) END END RegisterBySeparateRequests; Пакетный режим, добавление 1000 объектов: 952 msec Отдельный режим, добавление 1000 объектов с 1000 обращений к СУБД: 37152 msec Тест делался на localhost, по сети сейчас не могу, думаю, что разрыв будет ещё существеннее. |
Автор: | Борис Рюмшин [ Воскресенье, 22 Июнь, 2014 20:15 ] |
Заголовок сообщения: | Re: Mysql |
Это очевидно и без теста. Я просил сделать сравнение между "Пакетным INSERT" и INSERT ... VALUES. |
Автор: | Илья Ермаков [ Воскресенье, 22 Июнь, 2014 21:37 ] |
Заголовок сообщения: | Re: Mysql |
Так толку тестировать INSERT VALUES, если он невозможен для данной задачи. |
Автор: | albobin [ Понедельник, 23 Июнь, 2014 09:25 ] |
Заголовок сообщения: | Re: Mysql |
Илья Ермаков писал(а): Контекст проекта: небольшой заказ на сбор данных с трёх медицинских анализаторов. Делают мои студенты ... оффтоп: может быть полезно студентам для представления о том, во что вырастает "небольшой заказ на сбор данных с трёх медицинских анализаторов" у "серьёзных пацанов" http://intersystems.ru/trakcarelab/ |
Автор: | ilovb [ Понедельник, 23 Июнь, 2014 13:31 ] |
Заголовок сообщения: | Re: Mysql |
Илья, так сделайте в одну таблицу если нужна производительность. Вам места жалко? |
Автор: | Илья Ермаков [ Понедельник, 23 Июнь, 2014 18:05 ] |
Заголовок сообщения: | Re: Mysql |
Хотелось отработать наиболее прямой, универсальный способ рукодельного ORM. Всё в одну таблицу - это уже оптимизация под частный случай... По производительности - там с одного аппарата данные идут сразу после каждого анализа - и никаких узких мест быть не может. А вот с двух других сгружаться будут в пакетном режиме. И не хотелось иметь тормоз на этом пакетном режиме. Кстати, в отношении самого главного и сложного из трёх аппаратов (HEMOLUX-19) сегодня ребята оттестировали - работает системка... |
Автор: | Valery Solovey [ Среда, 25 Июнь, 2014 09:18 ] |
Заголовок сообщения: | Re: Mysql |
А предопределённые выражения той же производительности не добавили бы? Это вместо точки с запятой, которая, между прочим, сделала возможным это. Или вообще использовать хранимые процедуры. |
Автор: | Илья Ермаков [ Среда, 25 Июнь, 2014 10:58 ] |
Заголовок сообщения: | Re: Mysql |
А как скармливать хранимой процедуре массу записей для добавления? Ну и уже идёт завязка на базоспецифический синтаксис процедур. |
Автор: | Valery Solovey [ Четверг, 26 Июнь, 2014 17:26 ] |
Заголовок сообщения: | Re: Mysql |
Где-то видел анализ обработки запроса во времени для MySQL. Там говорилось, что время обработки одного запроса в целом можно поделить на 3 части: передача данных, разбор строки и поиск. Эти три части почти одинаковые. >А как скармливать хранимой процедуре массу записей для добавления? Вы, добавив обработку точки с запятой, сэкономили на времени передачи. Я же предлагаю вместо этого сэкономить на разборе строки запроса. >идёт завязка на базоспецифический синтаксис процедур. Вы про синтаксис объявления или вызова? Я не уверен, но мне кажется, что вызов процедуры одинаков для всех (или большинства) СУБД. А добавление процедур можно сделать и руками. В MySQL нет возможности делать процедуры с переменным числом параметров или передавать список в качестве параметра, но есть обходной путь - использовать вместо списков строки с разделителем, а внутри процедуры разбивать строки на подстроки стандартными SQL-функциями. |
Автор: | Илья Ермаков [ Четверг, 26 Июнь, 2014 18:10 ] |
Заголовок сообщения: | Re: Mysql |
Valery Solovey писал(а): Где-то видел анализ обработки запроса во времени для MySQL. Там говорилось, что время обработки одного запроса в целом можно поделить на 3 части: передача данных, разбор строки и поиск. Эти три части почти одинаковые. Тут вступает в силу ещё одна фаза: латентность запроса. Я как раз с этого и начал в первом сообщении. Передать данные потоком в одну сторону можно очень быстро, а вот обмен "запрос-ответ" дорого обходится. На стандартном стеке оборудования и протоколов больше нескольких сотен взаимообменов запросом-ответом в секунду Вы вряд ли получите. Тут трубопровод: скорость перекачивания нефти может быть 10 тонн в секунду, но длительность прохождения конкретной порции нефти от Орла до, допустим, Майданека будет много часов. А если Вы отправляете по пустой трубе эту тонну и ждёте обратно такую же тонну, то ещё в два раза больше. |
Автор: | Valery Solovey [ Пятница, 27 Июнь, 2014 09:32 ] |
Заголовок сообщения: | Re: Mysql |
Илья Ермаков писал(а): Тут вступает в силу ещё одна фаза: латентность запроса. Я как раз с этого и начал в первом сообщении. Передать данные потоком в одну сторону можно очень быстро, а вот обмен "запрос-ответ" дорого обходится. На стандартном стеке оборудования и протоколов больше нескольких сотен взаимообменов запросом-ответом в секунду Вы вряд ли получите. Про латентность я говорил, это фаза передачи данных. Я тут совсем забыл... Работа с БД идёт в блокирующем режиме, да? То есть, несколько соединений открывать бессмысленно, чтобы отправлять запросы параллельно? |
Автор: | Илья Ермаков [ Пятница, 27 Июнь, 2014 13:42 ] |
Заголовок сообщения: | Re: Mysql |
Угу. Драйвер ББ Ивана блокирующий. Хотя сам интерфейс подсистемы Sql допускает асинхронность... Но это уже какие-то навороты пошли. Ну, давайте прикинем - если просадка по быстродействию при последовательных запросов порядка 30 раз, что нам - открывать 30 соединений к базе параллельно? Ну, можно, но как-то... |
Автор: | adimetrius [ Среда, 14 Октябрь, 2020 23:05 ] |
Заголовок сообщения: | Re: Mysql |
Коллеги, я скачал подсистему Mysql с Oberoncore.ru, взялся компилировать, как сказано в Compile-List, вариант для Линукс, и тут же напоролся на IMPORT WinApi, WinOle в MysqlStrings (прямо в модуле отмечено красным). Это моя ошибка, или документация отстала от версии? Компонент по-прежнему кроссплатформен? |
Страница 2 из 2 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |