Сообщение В России опять напишут новый объектно-ориентированны от 17.04.2018 7:46
Изменено 17.04.2018 8:36 Sinclair
Re[54]: В России опять напишут новый объектно-ориентированны
Здравствуйте, vdimas, Вы писали:
V>Вроде, мы же уже выяснили, что ты был не в курсе про дефрагментацию индексов и деградацию быстродействия?
Неа. Мы пока что выяснили, что вы, коллега, полагали, что MyISAM в MySQL хранит индексы в том же файле, что и данные.
Про фрагментацию индексов мы ещё не разговаривали — в прошлый раз при моём уточняющем вопросе про "ресайз страницы" в MS SQL вы сослались на коллегу из курилки и сбежали из темы.
Я с удовольствием почитаю ваши очередные перлы про то, как "на самом" деле устроены B-tree индексы, и как "деградирует быстродействие" при "дефрагментации".
V>Мы про сценарий "склейки" сервака приложений и СУБД во всём этом топике обсуждаем.
V>Очередь запросов чудовищная в известных мне областях, для которых я подобную систему и предлагаю, собсно.
А, просто вы мечетесь, как заяц по огороду. В этой ветке я комментировал исключительно про неспособность никаких систем, кроме Акссеса, совместно работать с локальными и удалёнными данными.
Если хотите вернуться к in-proc/out-of-proc для высоконагруженного сервера, то можно поговорить и об этом.
V>Мы обкатали этот сценарий и показали его преимущество в GUI-приложениях.
Отож. Я прямо уж не знаю, что бы было с индустрией, если бы не вы.
V>В цикле.
V>И речь шла обо всём отображаемом наборе, а не вообще о всех данных в таблице.
Печалька. Ну, то есть клиппера вы всё-таки не видели. Жалко, у меня исходников не сохранилось. Дискетки столько не живут
V>Ты мне дай типизированную коллекцию, а не абстрактную.
Для чего?
V>В любом случае, коллекция выдаёт нетипизированные элементы и проверка их приведения тоже происходит в рантайм.
Конечно. И это делается ровно в одном методе.
V>Поэтому, типизированные коллекции были весьма популярны.
V>Настоящие, статически-типизированные.
V>В реальных Delphi-приложениях бывают произвольные коллекции.
V>В том числе писанные вовсе с 0-ля.
V>В большой системе таких коллекций больше, чем встроенных.
Ну вот у нас в проекте на сотню тысяч строк было три таких коллекции. На дельфи же не математику писали, а бизнес приложения.
V>Показана средняя скорость НЕ самого диска, а результатов у населения.
V>А там не факт, что тестируемая техника имеет PCIe 3.0, в пользовательском-то сегменте самая популярная до сих пор PCIe 2.0.
V>Но даже по твоей ссылке видно, что у некоторых пользователей бенчмарк даёт те самые 3.6 гига/с.
Повторюсь: maximum: 2,859. Результатов с 3.6 гига среди 20000 результатов не зарегистрировано.
А нас, пользователей RDBMS, интересует не этот максимум, а random 4k в mixed режиме. Где мы наблюдаем значительно более реалистичные 280 мегабайт в секунду. Не гига байт, а мега байт.
Память в рандом режиме всё ещё в сорок раз быстрее.
V>Покажи мне по твоей ссылке условия тестирования?
http://www.userbenchmark.com/Faq/What-is-sequential-read-speed/44
Можете скачать софтинку оттуда и проверить свою машину.
V>Продолжаем ликбез: на SSD-дисках любая относительно-длинная запись (длиннее строки хранения), даже про которую операционка рапортует как расположенную "в одной куче", де-факто "разбросана" по диску. SSD — это разновидность статической памяти, т.е. ей пофиг, насчёт в куче или не в куче, на физическом уровне там всё-равно обычный адресный доступ, как в оперативке.
Ухты! А чо ж тогда у него так различается скорость чтения в линейном режиме и покусочном? Там не всё так просто, как кажется.
V>>>Обрати внимание на графике на размер очереди запросов IO самого накопителя.
S>>Не вижу графика с размером очереди.
V>Надпись DQ=128 на графике — это длина очереди.
А, понятно. Ну вот, скажем, если сравнить очередь длиной в 64 с очередью длиной в 1, то ускорение всего в 4 раза. На вашей картинке при длине очереди в 128 намерили 800MB/s, но, поскольку кроме картинки, вы ничего не привели, то есть риск, что речь идёт о чистом чтении. Что в OLTP задаче не встречается.
V>>>Да хотя бы почему приложение на дельфях медленнее работает с базами данных при отображении в таблицах.
S>>Брр. Медленнее, чем что? С парадоксом дельфи работал просто прекрасно.
V>Медленнее при листании страниц.
V>Просто взять относительно большую выборку, схватить мышой бегунок на скролл-баре и погонять туда-сюда.
Ок, и почему же дельфи с Парадоксом будет работать медленнее, чем Access?
V>(блин, в каждом абзаце можно цокать и цокать языком)
V>В общем, 3-й FoxPro от 95-го года был уже графический.
V>А "окончательная" 5-й версия — от 97-го года.
V>Собсно с этой версии и пошла популярность FoxPro, на котором было разработано мильон GUI-приложух (последующие версии FoxPro от 5-го отличались не сильно).
У нас популярность фокспро началась задолго до 95го года. Большинство приложений было разработано в начале 90х на фокспро для ДОС, и использовалось вплоть до перехода на полноценные клиент-серверные решения.
Вот, например, ознакомьтесь с БЭСТ-4: http://best-trade.narod.ru/bestface.htm
Выпущен в 2000 году. Всё ещё никаких Visual Foxpro — банальный дос-режим, текстовый терминал, внутри — фокспро.
Возможно, в ваших кругах фокспро 3-5 кого-то и интересовали, но у нас его никто не пользовал. Поэтому рассматривать этот продукт я смысла не вижу.
V>Это я приводил для демонстрации, что наиболее эффективным способом работы с ISAM-базами было открытие навигируемого рекордсета по индексу. В этом случае чтение данных можно было производить прямо в операции отрисовки окна, без предварительного чтения. Так вот, недостаток FoxPro был в том, что он для отображения в таблице текущей страницы сначала должен был прочитать отображаемые строки, что создавало подтормаживания GUI.
Не уверен, что недостаток — именно в этом. Потому что способа отобразить строки, не читая, я не знаю. Или имеется в виду возможность успеть дёрнуть мышкой курсор ещё до того, как отрисуются все строки, и сэкономить 250мс на ожидании подгрузки?
V>ISAM вполне себе выбор для сервера приложений в трехзвенке.
V>Только не stateless псевдотрёхзвенке, как в случае HTTP-фронтенда, а настоящего stateful.
Чисто уточнить: здесь под ISAM подразумевается прямое управление курсорами? Все вот эти вот locate и seek? Вместо декларативного описания запросов, я ничего не перепутал?
V>Ну блин, как речь об ISAM, так ты проваливаешься в область сетевого доступа к файлам.
V>Это какой-то пипец.
V>При том, что мы даже разобрали My SQL, где в одной из его конфигураций над ISAM работает полноценный СУБД-процесс с исключительным доступом.
Ага. И это — та самая конфигурация, в которой невозможно даже сказать rollback tran, если по пути мы нарвались на нарушение ограничения.
V>При том, что любая среда программирования несла с собой справку?
Ага. Справку по форме 086-У. Вот, к примеру, с MSVS6.0 шла документация по WinAPI. По вопросу "работа с ком-портом" — ровно одно упоминание в CreateFile: что можно открыть файл с именем "COM1:" — и будет щасьте.
Как настраивать скорость передачи, биты контроля чётности — ничего. Нуль. Как проверить, пришли ли данные — угадывай. Пробовал открывать — щастья не было. Вроде даже иногда что-то читалось, но почему-то с пропусками и перебоями.
Тут справкой не отделаешься — нужна нормальная литература, с объяснением, как и что работает. А такого не было. Про ДОС были и книжки, с детальным описанием, как вешаться на прерывания, что куда писать, что откуда читать, и с примерами простейших программ.
V>Хотя, если уж по-справедливости относительно тех лет, то больше речь шла о доступе к машинному времени с нужной версией ОС.
V>Так-то получить машинное время под ДОС было проще, угу.
У меня было бесконечное машинное время, и ДОС, и винда. Вот только интернета не было. Поэтому приходилось пользоваться тем, что есть, и что работает.
V>Вопрос в том — можно ли делать move назад или устанавливать произвольную запись текущей.
V>https://docs.microsoft.com/en-us/sql/ado/reference/ado-api/move-method-ado?view=ssdt-18vs2017
V>А так же — курсор статический или динамический, если можно навигировать по записям туда-сюда.
Под капотом — всё равно операции чтения/записи.
V>Я примерно понимаю, о чём ты, но это ходьба по-кругу.
V>- получается, что страницы shared-memory ты предлагаешь использовать сугубо как транспортные, то бишь аргументы "зато нет копирования" фтопку, бо копирование будет дважды — на стороне сервака на страницу и на стороне клиента из страницы;
Ох-хо-хо. Кто-то кого-то не понимает.
Вот у нас есть кусок клиентского кода, допустим, вот такой:
Это я предполагаю, что у нас есть способ читать данные типизированно, а не вытаскивать VARIANT с последующим приведением.
Что у нас будет под капотом? Ясен хрен, что у рекордсета внутри — какой-то буфер. Рекордсет не читает одну запись. Он читает сразу, скажем, полмегабайта записей, включая последнюю. Если мы говорим об in-proc сервере, то это будет буфер файла. Возможно, как в MySQL, это будет отображение файла на память; возможно, там внутри будет прямо Read() в сырой массив.
Вызов операции чтения приведёт к проверке метаданных, поиску смещения текущей записи, разбору её заголовка в поисках смещения данных запрошенного поля, и конверсии. Потому, что внутри у нас поле хранится в Win1252 или UTF-8 или ещё как-то, а читаем мы его в UCS-2. Даже если бы мы вернулись в каменный век и сказали, что мы возвращаем сырые данные прямо в формате хранения, то пришлось бы внутри ReadString() делать nstrcpy, т.к. у нас даже 0-terminatоr не хранится.
А что будет в случае с Shared Memory? Да всё то же самое, только буфер заполняется другим процессом, а не системой.
Следующее чтение случится тогда, когда позиционирование рекордсета попробует выйти за пределы буфера — тогда у нас снова подкачается буфер, т.к. гонять данные по 4 байта очень дорого — что с диском, что с соседним процессом.
В обоих случаях под капотом происходит переключение контекста.
И это мы предполагаем совершенно безумную идею, что клиенту интересно разбираться с устройством таблиц и индексов. То есть он работает прямо с теми данными, которые хранятся.
А на самом деле, клиент выполняет запрос в духе
И получает на выходе рекордсет, который ни к какому файлу не относится. Поэтому сервер заботливо готовит буфер на своей стороне и говорит клиенту: "готово".
Тот забирает буфер и начинает с ним работать (т.е. читать данные). Идея "биндить курсор к GUI" работает только в одном малоинтересном сценарии: "редактирование справочников", где элементарная операция волшебно совпадает со строкой таблицы.
V>Мне всё еще требуется объяснять, почему out-of-proc существенно затратней?
Конечно требуется. Пока что вы ничего не обосновали, кроме "да в девяностые все это знали".
V>Я всё что угодно обыгрываю по производительности прямо замерам лабораторий Интел.
V>Работа у меня такая.
Да-да, а ещё вы очень скромный.
V>Они отключают шедуллинг ОС этого механизма, но не отключают сам механизм.
Чего?
V>Именно под задачи СУБД из виндов торчит АПИ навроде ReadFileScatter/WriteFileGather.
Ухты! Как интересно. Мне вот казалось, что эти АПИ совсем для другого.
Может, проиллюстрируете мне, как эти АПИ помогут мне прочесть с диска набор из десятка страничек, разбросанных по файлу?
V>Я нагуглил и данные тебе уже дал.
Ну, приличные люди дают не только картинку, но и ссылку на статью, в которой она упомянута.
V>>>А, может, ты забыл, что операции записи в shared-память провоцируют исключения ОС?
S>>Хуже — я про это даже не знал. А где прочитать про эти мифические исключения? Мне просто непонятно, для чего они могут быть нужны. Ведь shared memory ничем от обычной не отличается.
V>Shared-memory в Windows — это один из способов IO для файлов.
V>Самый эффективный способ для того самого IO для файлов, угу.
V>Литературы по отображаемым файлам — полно.
V>RTFM!
Ну вот нигде из того, что я читал, нету никаких упоминаний про то, что запись в shared-memory будет провоцировать какие-то исключения. Вот я и хочу, чтобы вы мне популярно объяснили, как это работает. Ну, вот, допустим, у меня "сервер" хочет отдать 64 килобайта данных "клиенту", и с этой целью заполняет буфер в shared memory путём банального цикла:
Сколько у нас произойдёт "исключений ОС"?
Изменится ли это количество, если мы вместо shared-memory буфера будем использовать "обычную" память?
V>На такой технике и таких скоростях и это прокатывало, и?
Не, не прокатывало. Там практики code review не было, но ради такого случая его провели, автора — уволили.
V>Или невозможности твоей схемы "буфер1 заняли, освободили буфер2 и так по-очереди" для shared memory, при локальном out-of-proc и при живом динамическом курсоре.
V>Да не, у "живого" курсора именно что амба, даже если связь восстановили.
"Живой" курсор — это вообще фикция. Классическая дырявая абстракция.
Системы, написанные "программистами живых курсоров" в девяностых годах до сих пор масштабируют путём запуска в терминальной сессии на супермегасервере.
И считают, что двести активных пользователей — это типа ого-го как много.
V>Просто открываешь forward-only и читаешь данные, кешируя их локально.
Воот. Потому что в нормальной распределённой среде нет такого понятия, как "живой курсор". Есть запрос, есть его результат на момент времени Х.
С ним можно работать.
V>Код синхронизации однократный для произвольных разных типов док-тов.
V>Всё-равно оперируемая схема строк БД зачитывается динамически.
Ну, тогда и с Аксессом разницы нет.
V>Раза в 2-3 только на совсем уж синтетических тестах в одном цикле.
V>А как более-мнее реальность, как начинаются развесистые графы объектов в памяти, так 10 раз аж бегом разницы по потребляемой памяти и быстродействию.
В типичных OLTP задачах
V>Ну я тебе давал уже реальные цифры по нейтивным системам.
V>Сотовые базы на узлах тоже работают аж бегом при самом жутком трафике из всех возможных.
Что такое "сотовые базы"? Это случайно не про роутеры на Эрланге рассказ?
V>Голая нейтивная конкатенация даёт примерно 3-5-тикратный прирост.
Хотелось бы посмотреть на результаты реальных замеров.
V>Но этого мало, мы же работаем через абстракции навроде StreamWriter, а там разница чудовищная по итогу выходит, более 20 раз.
А тут-то откуда?
V>Нейтивный парсинг HTTP-заголовков даёт примено столько же, в 3-5 раз и умножай это на более эффективный ввод/вывод в сравнении с дотнетными Stream.
Наверное, надо всё же складывать, а не умножать.
V>При применении всякой "полигональной" памяти, т.е. алгоритмов управления памятью, которые хорошо заточены именно под серверные задачи навроде вопрос-ответ — там еще +50% производительности прибавляй, т.к. управление памятью становится де-факто бесплатное от слова совсем.
Неужто можно инкремент поинтера обогнать?
V>Набор SQL-запросов у вас фиксированный, их "оптимизированные" версии можно нагенерить в офлайне, в кач-ве шага билда.
Ну, вот до этого у меня никак руки не доходят дописать типичный OLTP запрос и посмотреть, сколько там будет вариантов плана.
Есть существенные подозрения, что надо смотреть не в сторону офлайна, а в сторону рантайм-компиляции.
Просто большинство современных движков писалось в такую эпоху, когда встроить компилятор в приложение было малореально.
Сейчас нет никакой проблемы за миллисекунды получить из плана запросов его бинарную версию, используя коробочные технологии.
Тот же Microsoft предлагает писать триггеры на C# и компилировать их статически, вместо того, чтобы сделать банальный компилятор из T-SQL в MSIL и разогнать существующие базы без вложений труда.
V>Вот как раз периодически замеряем, стабильно примерно в 10 раз разница.
Между чем и чем?
S>>А на отдаче HTML сильно много не сэкономишь. Ну, может процентов 20% за счёт более агрессивного инлайна в клинических случаях.
V>Не так давно в местном плюсовом форуме соревновались в библиотеках форматирования текста.
V>Разница более 8 раз с традиционными STL-потоками iostream, а те работают быстрее дотнетных StreamWriter.
Ссылка бы помогла.
V>Нейтив — это нейтив.
V>Там любое серверное приложение сразу из себя автомат представляет (или набор автоматов), т.е. прямо начиная от самой низкоуровневой архитектуры. Ничего другое на серверной стороне смысла не имеет.
Для интересу можно сравнить архитектуру нативного Апача и нативного lightthpd или nginx. Чтобы понять, что не любое нативное приложение способно нормально работать. Ruki.sys никто не отменял.
V>Вот, еще и дотнет за тебя решает, как ты будешь коннекшены использовать.
V>А что один и тот же коннекшен можно делить м/у разными запросами, если из одного и того же потока — этого ты через дотнет, увы, не провернёшь. Это можно было через native client или возвращённый на днях к жизни OLEDB-драйвер:
V>https://blogs.msdn.microsoft.com/sqlnativeclient/2017/10/06/announcing-the-new-release-of-ole-db-driver-for-sql-server/
Это про MARS? Сомнительная фича. Для любителей "живых курсоров" и задрачивания сервера в режиме "N+1" аka master-detail.
V>Вроде, мы же уже выяснили, что ты был не в курсе про дефрагментацию индексов и деградацию быстродействия?
Неа. Мы пока что выяснили, что вы, коллега, полагали, что MyISAM в MySQL хранит индексы в том же файле, что и данные.
Про фрагментацию индексов мы ещё не разговаривали — в прошлый раз при моём уточняющем вопросе про "ресайз страницы" в MS SQL вы сослались на коллегу из курилки и сбежали из темы.
Я с удовольствием почитаю ваши очередные перлы про то, как "на самом" деле устроены B-tree индексы, и как "деградирует быстродействие" при "дефрагментации".
V>Мы про сценарий "склейки" сервака приложений и СУБД во всём этом топике обсуждаем.
V>Очередь запросов чудовищная в известных мне областях, для которых я подобную систему и предлагаю, собсно.
А, просто вы мечетесь, как заяц по огороду. В этой ветке я комментировал исключительно про неспособность никаких систем, кроме Акссеса, совместно работать с локальными и удалёнными данными.
Если хотите вернуться к in-proc/out-of-proc для высоконагруженного сервера, то можно поговорить и об этом.
V>Мы обкатали этот сценарий и показали его преимущество в GUI-приложениях.
Отож. Я прямо уж не знаю, что бы было с индустрией, если бы не вы.
V>В цикле.
V>И речь шла обо всём отображаемом наборе, а не вообще о всех данных в таблице.
Печалька. Ну, то есть клиппера вы всё-таки не видели. Жалко, у меня исходников не сохранилось. Дискетки столько не живут
V>Ты мне дай типизированную коллекцию, а не абстрактную.
Для чего?
V>В любом случае, коллекция выдаёт нетипизированные элементы и проверка их приведения тоже происходит в рантайм.
Конечно. И это делается ровно в одном методе.
V>Поэтому, типизированные коллекции были весьма популярны.
V>Настоящие, статически-типизированные.
V>В реальных Delphi-приложениях бывают произвольные коллекции.
V>В том числе писанные вовсе с 0-ля.
V>В большой системе таких коллекций больше, чем встроенных.
Ну вот у нас в проекте на сотню тысяч строк было три таких коллекции. На дельфи же не математику писали, а бизнес приложения.
V>Показана средняя скорость НЕ самого диска, а результатов у населения.
V>А там не факт, что тестируемая техника имеет PCIe 3.0, в пользовательском-то сегменте самая популярная до сих пор PCIe 2.0.
V>Но даже по твоей ссылке видно, что у некоторых пользователей бенчмарк даёт те самые 3.6 гига/с.
Повторюсь: maximum: 2,859. Результатов с 3.6 гига среди 20000 результатов не зарегистрировано.
А нас, пользователей RDBMS, интересует не этот максимум, а random 4k в mixed режиме. Где мы наблюдаем значительно более реалистичные 280 мегабайт в секунду. Не гига байт, а мега байт.
Память в рандом режиме всё ещё в сорок раз быстрее.
V>Покажи мне по твоей ссылке условия тестирования?
http://www.userbenchmark.com/Faq/What-is-sequential-read-speed/44
Можете скачать софтинку оттуда и проверить свою машину.
V>Продолжаем ликбез: на SSD-дисках любая относительно-длинная запись (длиннее строки хранения), даже про которую операционка рапортует как расположенную "в одной куче", де-факто "разбросана" по диску. SSD — это разновидность статической памяти, т.е. ей пофиг, насчёт в куче или не в куче, на физическом уровне там всё-равно обычный адресный доступ, как в оперативке.
Ухты! А чо ж тогда у него так различается скорость чтения в линейном режиме и покусочном? Там не всё так просто, как кажется.
V>>>Обрати внимание на графике на размер очереди запросов IO самого накопителя.
S>>Не вижу графика с размером очереди.
V>Надпись DQ=128 на графике — это длина очереди.
А, понятно. Ну вот, скажем, если сравнить очередь длиной в 64 с очередью длиной в 1, то ускорение всего в 4 раза. На вашей картинке при длине очереди в 128 намерили 800MB/s, но, поскольку кроме картинки, вы ничего не привели, то есть риск, что речь идёт о чистом чтении. Что в OLTP задаче не встречается.
V>>>Да хотя бы почему приложение на дельфях медленнее работает с базами данных при отображении в таблицах.
S>>Брр. Медленнее, чем что? С парадоксом дельфи работал просто прекрасно.
V>Медленнее при листании страниц.
V>Просто взять относительно большую выборку, схватить мышой бегунок на скролл-баре и погонять туда-сюда.
Ок, и почему же дельфи с Парадоксом будет работать медленнее, чем Access?
V>(блин, в каждом абзаце можно цокать и цокать языком)
V>В общем, 3-й FoxPro от 95-го года был уже графический.
V>А "окончательная" 5-й версия — от 97-го года.
V>Собсно с этой версии и пошла популярность FoxPro, на котором было разработано мильон GUI-приложух (последующие версии FoxPro от 5-го отличались не сильно).
У нас популярность фокспро началась задолго до 95го года. Большинство приложений было разработано в начале 90х на фокспро для ДОС, и использовалось вплоть до перехода на полноценные клиент-серверные решения.
Вот, например, ознакомьтесь с БЭСТ-4: http://best-trade.narod.ru/bestface.htm
Выпущен в 2000 году. Всё ещё никаких Visual Foxpro — банальный дос-режим, текстовый терминал, внутри — фокспро.
Возможно, в ваших кругах фокспро 3-5 кого-то и интересовали, но у нас его никто не пользовал. Поэтому рассматривать этот продукт я смысла не вижу.
V>Это я приводил для демонстрации, что наиболее эффективным способом работы с ISAM-базами было открытие навигируемого рекордсета по индексу. В этом случае чтение данных можно было производить прямо в операции отрисовки окна, без предварительного чтения. Так вот, недостаток FoxPro был в том, что он для отображения в таблице текущей страницы сначала должен был прочитать отображаемые строки, что создавало подтормаживания GUI.
Не уверен, что недостаток — именно в этом. Потому что способа отобразить строки, не читая, я не знаю. Или имеется в виду возможность успеть дёрнуть мышкой курсор ещё до того, как отрисуются все строки, и сэкономить 250мс на ожидании подгрузки?
V>ISAM вполне себе выбор для сервера приложений в трехзвенке.
V>Только не stateless псевдотрёхзвенке, как в случае HTTP-фронтенда, а настоящего stateful.
Чисто уточнить: здесь под ISAM подразумевается прямое управление курсорами? Все вот эти вот locate и seek? Вместо декларативного описания запросов, я ничего не перепутал?
V>Ну блин, как речь об ISAM, так ты проваливаешься в область сетевого доступа к файлам.
V>Это какой-то пипец.
V>При том, что мы даже разобрали My SQL, где в одной из его конфигураций над ISAM работает полноценный СУБД-процесс с исключительным доступом.
Ага. И это — та самая конфигурация, в которой невозможно даже сказать rollback tran, если по пути мы нарвались на нарушение ограничения.
V>При том, что любая среда программирования несла с собой справку?
Ага. Справку по форме 086-У. Вот, к примеру, с MSVS6.0 шла документация по WinAPI. По вопросу "работа с ком-портом" — ровно одно упоминание в CreateFile: что можно открыть файл с именем "COM1:" — и будет щасьте.
Как настраивать скорость передачи, биты контроля чётности — ничего. Нуль. Как проверить, пришли ли данные — угадывай. Пробовал открывать — щастья не было. Вроде даже иногда что-то читалось, но почему-то с пропусками и перебоями.
Тут справкой не отделаешься — нужна нормальная литература, с объяснением, как и что работает. А такого не было. Про ДОС были и книжки, с детальным описанием, как вешаться на прерывания, что куда писать, что откуда читать, и с примерами простейших программ.
V>Хотя, если уж по-справедливости относительно тех лет, то больше речь шла о доступе к машинному времени с нужной версией ОС.
V>Так-то получить машинное время под ДОС было проще, угу.
У меня было бесконечное машинное время, и ДОС, и винда. Вот только интернета не было. Поэтому приходилось пользоваться тем, что есть, и что работает.
V>Вопрос в том — можно ли делать move назад или устанавливать произвольную запись текущей.
V>https://docs.microsoft.com/en-us/sql/ado/reference/ado-api/move-method-ado?view=ssdt-18vs2017
V>А так же — курсор статический или динамический, если можно навигировать по записям туда-сюда.
Под капотом — всё равно операции чтения/записи.
V>Я примерно понимаю, о чём ты, но это ходьба по-кругу.
V>- получается, что страницы shared-memory ты предлагаешь использовать сугубо как транспортные, то бишь аргументы "зато нет копирования" фтопку, бо копирование будет дважды — на стороне сервака на страницу и на стороне клиента из страницы;
Ох-хо-хо. Кто-то кого-то не понимает.
Вот у нас есть кусок клиентского кода, допустим, вот такой:
rs.MoveLast()
var s = rs.ReadString(12) // reading the field #12
Это я предполагаю, что у нас есть способ читать данные типизированно, а не вытаскивать VARIANT с последующим приведением.
Что у нас будет под капотом? Ясен хрен, что у рекордсета внутри — какой-то буфер. Рекордсет не читает одну запись. Он читает сразу, скажем, полмегабайта записей, включая последнюю. Если мы говорим об in-proc сервере, то это будет буфер файла. Возможно, как в MySQL, это будет отображение файла на память; возможно, там внутри будет прямо Read() в сырой массив.
Вызов операции чтения приведёт к проверке метаданных, поиску смещения текущей записи, разбору её заголовка в поисках смещения данных запрошенного поля, и конверсии. Потому, что внутри у нас поле хранится в Win1252 или UTF-8 или ещё как-то, а читаем мы его в UCS-2. Даже если бы мы вернулись в каменный век и сказали, что мы возвращаем сырые данные прямо в формате хранения, то пришлось бы внутри ReadString() делать nstrcpy, т.к. у нас даже 0-terminatоr не хранится.
А что будет в случае с Shared Memory? Да всё то же самое, только буфер заполняется другим процессом, а не системой.
Следующее чтение случится тогда, когда позиционирование рекордсета попробует выйти за пределы буфера — тогда у нас снова подкачается буфер, т.к. гонять данные по 4 байта очень дорого — что с диском, что с соседним процессом.
В обоих случаях под капотом происходит переключение контекста.
И это мы предполагаем совершенно безумную идею, что клиенту интересно разбираться с устройством таблиц и индексов. То есть он работает прямо с теми данными, которые хранятся.
А на самом деле, клиент выполняет запрос в духе
select @docId, Commodity, case when Amount-RunQty>0 then Quantity else Amount-RunQty+Quantity end as moveQty, id from
(select oi.Commodity, oi.Amount, coalesce(RunQty, 0) as RunQty, coalesce(Quantity, 0) as Quantity, remainders.id from
OrderItems oi left join
(select id, Commodity, Quantity, (sum(Quantity) over(partition by Commodity order by ArrivalDate asc)) as RunQty from Consignments) remainders
on oi.Commodity = remainders.Commodity and remainders.RunQty - Quantity < oi.Amount) itemRemainders
И получает на выходе рекордсет, который ни к какому файлу не относится. Поэтому сервер заботливо готовит буфер на своей стороне и говорит клиенту: "готово".
Тот забирает буфер и начинает с ним работать (т.е. читать данные). Идея "биндить курсор к GUI" работает только в одном малоинтересном сценарии: "редактирование справочников", где элементарная операция волшебно совпадает со строкой таблицы.
V>Мне всё еще требуется объяснять, почему out-of-proc существенно затратней?
Конечно требуется. Пока что вы ничего не обосновали, кроме "да в девяностые все это знали".
V>Я всё что угодно обыгрываю по производительности прямо замерам лабораторий Интел.
V>Работа у меня такая.
Да-да, а ещё вы очень скромный.
V>Они отключают шедуллинг ОС этого механизма, но не отключают сам механизм.
Чего?
V>Именно под задачи СУБД из виндов торчит АПИ навроде ReadFileScatter/WriteFileGather.
Ухты! Как интересно. Мне вот казалось, что эти АПИ совсем для другого.
Может, проиллюстрируете мне, как эти АПИ помогут мне прочесть с диска набор из десятка страничек, разбросанных по файлу?
V>Я нагуглил и данные тебе уже дал.
Ну, приличные люди дают не только картинку, но и ссылку на статью, в которой она упомянута.
V>>>А, может, ты забыл, что операции записи в shared-память провоцируют исключения ОС?
S>>Хуже — я про это даже не знал. А где прочитать про эти мифические исключения? Мне просто непонятно, для чего они могут быть нужны. Ведь shared memory ничем от обычной не отличается.
V>Shared-memory в Windows — это один из способов IO для файлов.
V>Самый эффективный способ для того самого IO для файлов, угу.
V>Литературы по отображаемым файлам — полно.
V>RTFM!
Ну вот нигде из того, что я читал, нету никаких упоминаний про то, что запись в shared-memory будет провоцировать какие-то исключения. Вот я и хочу, чтобы вы мне популярно объяснили, как это работает. Ну, вот, допустим, у меня "сервер" хочет отдать 64 килобайта данных "клиенту", и с этой целью заполняет буфер в shared memory путём банального цикла:
for(i=0;i<16384;i++)
buffer[i] = i;
Сколько у нас произойдёт "исключений ОС"?
Изменится ли это количество, если мы вместо shared-memory буфера будем использовать "обычную" память?
V>На такой технике и таких скоростях и это прокатывало, и?
Не, не прокатывало. Там практики code review не было, но ради такого случая его провели, автора — уволили.
V>Или невозможности твоей схемы "буфер1 заняли, освободили буфер2 и так по-очереди" для shared memory, при локальном out-of-proc и при живом динамическом курсоре.
V>Да не, у "живого" курсора именно что амба, даже если связь восстановили.
"Живой" курсор — это вообще фикция. Классическая дырявая абстракция.
Системы, написанные "программистами живых курсоров" в девяностых годах до сих пор масштабируют путём запуска в терминальной сессии на супермегасервере.
И считают, что двести активных пользователей — это типа ого-го как много.
V>Просто открываешь forward-only и читаешь данные, кешируя их локально.
Воот. Потому что в нормальной распределённой среде нет такого понятия, как "живой курсор". Есть запрос, есть его результат на момент времени Х.
С ним можно работать.
V>Код синхронизации однократный для произвольных разных типов док-тов.
V>Всё-равно оперируемая схема строк БД зачитывается динамически.
Ну, тогда и с Аксессом разницы нет.
V>Раза в 2-3 только на совсем уж синтетических тестах в одном цикле.
V>А как более-мнее реальность, как начинаются развесистые графы объектов в памяти, так 10 раз аж бегом разницы по потребляемой памяти и быстродействию.
В типичных OLTP задачах
V>Ну я тебе давал уже реальные цифры по нейтивным системам.
V>Сотовые базы на узлах тоже работают аж бегом при самом жутком трафике из всех возможных.
Что такое "сотовые базы"? Это случайно не про роутеры на Эрланге рассказ?
V>Голая нейтивная конкатенация даёт примерно 3-5-тикратный прирост.
Хотелось бы посмотреть на результаты реальных замеров.
V>Но этого мало, мы же работаем через абстракции навроде StreamWriter, а там разница чудовищная по итогу выходит, более 20 раз.
А тут-то откуда?
V>Нейтивный парсинг HTTP-заголовков даёт примено столько же, в 3-5 раз и умножай это на более эффективный ввод/вывод в сравнении с дотнетными Stream.
Наверное, надо всё же складывать, а не умножать.
V>При применении всякой "полигональной" памяти, т.е. алгоритмов управления памятью, которые хорошо заточены именно под серверные задачи навроде вопрос-ответ — там еще +50% производительности прибавляй, т.к. управление памятью становится де-факто бесплатное от слова совсем.
Неужто можно инкремент поинтера обогнать?
V>Набор SQL-запросов у вас фиксированный, их "оптимизированные" версии можно нагенерить в офлайне, в кач-ве шага билда.
Ну, вот до этого у меня никак руки не доходят дописать типичный OLTP запрос и посмотреть, сколько там будет вариантов плана.
Есть существенные подозрения, что надо смотреть не в сторону офлайна, а в сторону рантайм-компиляции.
Просто большинство современных движков писалось в такую эпоху, когда встроить компилятор в приложение было малореально.
Сейчас нет никакой проблемы за миллисекунды получить из плана запросов его бинарную версию, используя коробочные технологии.
Тот же Microsoft предлагает писать триггеры на C# и компилировать их статически, вместо того, чтобы сделать банальный компилятор из T-SQL в MSIL и разогнать существующие базы без вложений труда.
V>Вот как раз периодически замеряем, стабильно примерно в 10 раз разница.
Между чем и чем?
S>>А на отдаче HTML сильно много не сэкономишь. Ну, может процентов 20% за счёт более агрессивного инлайна в клинических случаях.
V>Не так давно в местном плюсовом форуме соревновались в библиотеках форматирования текста.
V>Разница более 8 раз с традиционными STL-потоками iostream, а те работают быстрее дотнетных StreamWriter.
Ссылка бы помогла.
V>Нейтив — это нейтив.
V>Там любое серверное приложение сразу из себя автомат представляет (или набор автоматов), т.е. прямо начиная от самой низкоуровневой архитектуры. Ничего другое на серверной стороне смысла не имеет.
Для интересу можно сравнить архитектуру нативного Апача и нативного lightthpd или nginx. Чтобы понять, что не любое нативное приложение способно нормально работать. Ruki.sys никто не отменял.
V>Вот, еще и дотнет за тебя решает, как ты будешь коннекшены использовать.
V>А что один и тот же коннекшен можно делить м/у разными запросами, если из одного и того же потока — этого ты через дотнет, увы, не провернёшь. Это можно было через native client или возвращённый на днях к жизни OLEDB-драйвер:
V>https://blogs.msdn.microsoft.com/sqlnativeclient/2017/10/06/announcing-the-new-release-of-ole-db-driver-for-sql-server/
Это про MARS? Сомнительная фича. Для любителей "живых курсоров" и задрачивания сервера в режиме "N+1" аka master-detail.
В России опять напишут новый объектно-ориентированны
Здравствуйте, vdimas, Вы писали:
V>Вроде, мы же уже выяснили, что ты был не в курсе про дефрагментацию индексов и деградацию быстродействия?
Неа. Мы пока что выяснили, что вы, коллега, полагали, что MyISAM в MySQL хранит индексы в том же файле, что и данные.
Про фрагментацию индексов мы ещё не разговаривали — в прошлый раз при моём уточняющем вопросе про "ресайз страницы" в MS SQL вы сослались на коллегу из курилки и сбежали из темы.
Я с удовольствием почитаю ваши очередные перлы про то, как "на самом" деле устроены B-tree индексы, и как "деградирует быстродействие" при "дефрагментации".
V>Мы про сценарий "склейки" сервака приложений и СУБД во всём этом топике обсуждаем.
V>Очередь запросов чудовищная в известных мне областях, для которых я подобную систему и предлагаю, собсно.
А, просто вы мечетесь, как заяц по огороду. В этой ветке я комментировал исключительно про неспособность никаких систем, кроме Акссеса, совместно работать с локальными и удалёнными данными.
Если хотите вернуться к in-proc/out-of-proc для высоконагруженного сервера, то можно поговорить и об этом.
V>Мы обкатали этот сценарий и показали его преимущество в GUI-приложениях.
Отож. Я прямо уж не знаю, что бы было с индустрией, если бы не вы.
V>В цикле.
V>И речь шла обо всём отображаемом наборе, а не вообще о всех данных в таблице.
Печалька. Ну, то есть клиппера вы всё-таки не видели. Жалко, у меня исходников не сохранилось. Дискетки столько не живут
V>Ты мне дай типизированную коллекцию, а не абстрактную.
Для чего?
V>В любом случае, коллекция выдаёт нетипизированные элементы и проверка их приведения тоже происходит в рантайм.
Конечно. И это делается ровно в одном методе.
V>Поэтому, типизированные коллекции были весьма популярны.
V>Настоящие, статически-типизированные.
V>В реальных Delphi-приложениях бывают произвольные коллекции.
V>В том числе писанные вовсе с 0-ля.
V>В большой системе таких коллекций больше, чем встроенных.
Ну вот у нас в проекте на сотню тысяч строк было три таких коллекции. На дельфи же не математику писали, а бизнес приложения.
V>Показана средняя скорость НЕ самого диска, а результатов у населения.
V>А там не факт, что тестируемая техника имеет PCIe 3.0, в пользовательском-то сегменте самая популярная до сих пор PCIe 2.0.
V>Но даже по твоей ссылке видно, что у некоторых пользователей бенчмарк даёт те самые 3.6 гига/с.
Повторюсь: maximum: 2,859. Результатов с 3.6 гига среди 20000 результатов не зарегистрировано.
А нас, пользователей RDBMS, интересует не этот максимум, а random 4k в mixed режиме. Где мы наблюдаем значительно более реалистичные 280 мегабайт в секунду. Не гига байт, а мега байт.
Память в рандом режиме всё ещё в сорок раз быстрее.
V>Покажи мне по твоей ссылке условия тестирования?
http://www.userbenchmark.com/Faq/What-is-sequential-read-speed/44
Можете скачать софтинку оттуда и проверить свою машину.
V>Продолжаем ликбез: на SSD-дисках любая относительно-длинная запись (длиннее строки хранения), даже про которую операционка рапортует как расположенную "в одной куче", де-факто "разбросана" по диску. SSD — это разновидность статической памяти, т.е. ей пофиг, насчёт в куче или не в куче, на физическом уровне там всё-равно обычный адресный доступ, как в оперативке.
Ухты! А чо ж тогда у него так различается скорость чтения в линейном режиме и покусочном? Там не всё так просто, как кажется.
V>>>Обрати внимание на графике на размер очереди запросов IO самого накопителя.
S>>Не вижу графика с размером очереди.
V>Надпись DQ=128 на графике — это длина очереди.
А, понятно. Ну вот, скажем, если сравнить очередь длиной в 64 с очередью длиной в 1, то ускорение всего в 4 раза. На вашей картинке при длине очереди в 128 намерили 800MB/s, но, поскольку кроме картинки, вы ничего не привели, то есть риск, что речь идёт о чистом чтении. Что в OLTP задаче не встречается.
V>>>Да хотя бы почему приложение на дельфях медленнее работает с базами данных при отображении в таблицах.
S>>Брр. Медленнее, чем что? С парадоксом дельфи работал просто прекрасно.
V>Медленнее при листании страниц.
V>Просто взять относительно большую выборку, схватить мышой бегунок на скролл-баре и погонять туда-сюда.
Ок, и почему же дельфи с Парадоксом будет работать медленнее, чем Access?
V>(блин, в каждом абзаце можно цокать и цокать языком)
V>В общем, 3-й FoxPro от 95-го года был уже графический.
V>А "окончательная" 5-й версия — от 97-го года.
V>Собсно с этой версии и пошла популярность FoxPro, на котором было разработано мильон GUI-приложух (последующие версии FoxPro от 5-го отличались не сильно).
У нас популярность фокспро началась задолго до 95го года. Большинство приложений было разработано в начале 90х на фокспро для ДОС, и использовалось вплоть до перехода на полноценные клиент-серверные решения.
Вот, например, ознакомьтесь с БЭСТ-4: http://best-trade.narod.ru/bestface.htm
Выпущен в 2000 году. Всё ещё никаких Visual Foxpro — банальный дос-режим, текстовый терминал, внутри — фокспро.
Возможно, в ваших кругах фокспро 3-5 кого-то и интересовали, но у нас его никто не пользовал. Поэтому рассматривать этот продукт я смысла не вижу.
V>Это я приводил для демонстрации, что наиболее эффективным способом работы с ISAM-базами было открытие навигируемого рекордсета по индексу. В этом случае чтение данных можно было производить прямо в операции отрисовки окна, без предварительного чтения. Так вот, недостаток FoxPro был в том, что он для отображения в таблице текущей страницы сначала должен был прочитать отображаемые строки, что создавало подтормаживания GUI.
Не уверен, что недостаток — именно в этом. Потому что способа отобразить строки, не читая, я не знаю. Или имеется в виду возможность успеть дёрнуть мышкой курсор ещё до того, как отрисуются все строки, и сэкономить 250мс на ожидании подгрузки?
V>ISAM вполне себе выбор для сервера приложений в трехзвенке.
V>Только не stateless псевдотрёхзвенке, как в случае HTTP-фронтенда, а настоящего stateful.
Чисто уточнить: здесь под ISAM подразумевается прямое управление курсорами? Все вот эти вот locate и seek? Вместо декларативного описания запросов, я ничего не перепутал?
V>Ну блин, как речь об ISAM, так ты проваливаешься в область сетевого доступа к файлам.
V>Это какой-то пипец.
V>При том, что мы даже разобрали My SQL, где в одной из его конфигураций над ISAM работает полноценный СУБД-процесс с исключительным доступом.
Ага. И это — та самая конфигурация, в которой невозможно даже сказать rollback tran, если по пути мы нарвались на нарушение ограничения.
V>При том, что любая среда программирования несла с собой справку?
Ага. Справку по форме 086-У. Вот, к примеру, с MSVS6.0 шла документация по WinAPI. По вопросу "работа с ком-портом" — ровно одно упоминание в CreateFile: что можно открыть файл с именем "COM1:" — и будет щасьте.
Как настраивать скорость передачи, биты контроля чётности — ничего. Нуль. Как проверить, пришли ли данные — угадывай. Пробовал открывать — щастья не было. Вроде даже иногда что-то читалось, но почему-то с пропусками и перебоями.
Тут справкой не отделаешься — нужна нормальная литература, с объяснением, как и что работает. А такого не было. Про ДОС были и книжки, с детальным описанием, как вешаться на прерывания, что куда писать, что откуда читать, и с примерами простейших программ.
V>Хотя, если уж по-справедливости относительно тех лет, то больше речь шла о доступе к машинному времени с нужной версией ОС.
V>Так-то получить машинное время под ДОС было проще, угу.
У меня было бесконечное машинное время, и ДОС, и винда. Вот только интернета не было. Поэтому приходилось пользоваться тем, что есть, и что работает.
V>Вопрос в том — можно ли делать move назад или устанавливать произвольную запись текущей.
V>https://docs.microsoft.com/en-us/sql/ado/reference/ado-api/move-method-ado?view=ssdt-18vs2017
V>А так же — курсор статический или динамический, если можно навигировать по записям туда-сюда.
Под капотом — всё равно операции чтения/записи.
V>Я примерно понимаю, о чём ты, но это ходьба по-кругу.
V>- получается, что страницы shared-memory ты предлагаешь использовать сугубо как транспортные, то бишь аргументы "зато нет копирования" фтопку, бо копирование будет дважды — на стороне сервака на страницу и на стороне клиента из страницы;
Ох-хо-хо. Кто-то кого-то не понимает.
Вот у нас есть кусок клиентского кода, допустим, вот такой:
Это я предполагаю, что у нас есть способ читать данные типизированно, а не вытаскивать VARIANT с последующим приведением.
Что у нас будет под капотом? Ясен хрен, что у рекордсета внутри — какой-то буфер. Рекордсет не читает одну запись. Он читает сразу, скажем, полмегабайта записей, включая последнюю. Если мы говорим об in-proc сервере, то это будет буфер файла. Возможно, как в MySQL, это будет отображение файла на память; возможно, там внутри будет прямо Read() в сырой массив.
Вызов операции чтения приведёт к проверке метаданных, поиску смещения текущей записи, разбору её заголовка в поисках смещения данных запрошенного поля, и конверсии. Потому, что внутри у нас поле хранится в Win1252 или UTF-8 или ещё как-то, а читаем мы его в UCS-2. Даже если бы мы вернулись в каменный век и сказали, что мы возвращаем сырые данные прямо в формате хранения, то пришлось бы внутри ReadString() делать nstrcpy, т.к. у нас даже 0-terminatоr не хранится.
А что будет в случае с Shared Memory? Да всё то же самое, только буфер заполняется другим процессом, а не системой.
Следующее чтение случится тогда, когда позиционирование рекордсета попробует выйти за пределы буфера — тогда у нас снова подкачается буфер, т.к. гонять данные по 4 байта очень дорого — что с диском, что с соседним процессом.
В обоих случаях под капотом происходит переключение контекста.
И это мы предполагаем совершенно безумную идею, что клиенту интересно разбираться с устройством таблиц и индексов. То есть он работает прямо с теми данными, которые хранятся.
А на самом деле, клиент выполняет запрос в духе
И получает на выходе рекордсет, который ни к какому файлу не относится. Поэтому сервер заботливо готовит буфер на своей стороне и говорит клиенту: "готово".
Тот забирает буфер и начинает с ним работать (т.е. читать данные). Идея "биндить курсор к GUI" работает только в одном малоинтересном сценарии: "редактирование справочников", где элементарная операция волшебно совпадает со строкой таблицы.
V>Мне всё еще требуется объяснять, почему out-of-proc существенно затратней?
Конечно требуется. Пока что вы ничего не обосновали, кроме "да в девяностые все это знали".
V>Я всё что угодно обыгрываю по производительности прямо замерам лабораторий Интел.
V>Работа у меня такая.
Да-да, а ещё вы очень скромный.
V>Они отключают шедуллинг ОС этого механизма, но не отключают сам механизм.
Чего?
V>Именно под задачи СУБД из виндов торчит АПИ навроде ReadFileScatter/WriteFileGather.
Ухты! Как интересно. Мне вот казалось, что эти АПИ совсем для другого.
Может, проиллюстрируете мне, как эти АПИ помогут мне прочесть с диска набор из десятка страничек, разбросанных по файлу?
V>Я нагуглил и данные тебе уже дал.
Ну, приличные люди дают не только картинку, но и ссылку на статью, в которой она упомянута.
V>>>А, может, ты забыл, что операции записи в shared-память провоцируют исключения ОС?
S>>Хуже — я про это даже не знал. А где прочитать про эти мифические исключения? Мне просто непонятно, для чего они могут быть нужны. Ведь shared memory ничем от обычной не отличается.
V>Shared-memory в Windows — это один из способов IO для файлов.
V>Самый эффективный способ для того самого IO для файлов, угу.
V>Литературы по отображаемым файлам — полно.
V>RTFM!
Ну вот нигде из того, что я читал, нету никаких упоминаний про то, что запись в shared-memory будет провоцировать какие-то исключения. Вот я и хочу, чтобы вы мне популярно объяснили, как это работает. Ну, вот, допустим, у меня "сервер" хочет отдать 64 килобайта данных "клиенту", и с этой целью заполняет буфер в shared memory путём банального цикла:
Сколько у нас произойдёт "исключений ОС"?
Изменится ли это количество, если мы вместо shared-memory буфера будем использовать "обычную" память?
V>На такой технике и таких скоростях и это прокатывало, и?
Не, не прокатывало. Там практики code review не было, но ради такого случая его провели, автора — уволили.
V>Или невозможности твоей схемы "буфер1 заняли, освободили буфер2 и так по-очереди" для shared memory, при локальном out-of-proc и при живом динамическом курсоре.
V>Да не, у "живого" курсора именно что амба, даже если связь восстановили.
"Живой" курсор — это вообще фикция. Классическая дырявая абстракция.
Системы, написанные "программистами живых курсоров" в девяностых годах до сих пор масштабируют путём запуска в терминальной сессии на супермегасервере.
И считают, что двести активных пользователей — это типа ого-го как много.
V>Просто открываешь forward-only и читаешь данные, кешируя их локально.
Воот. Потому что в нормальной распределённой среде нет такого понятия, как "живой курсор". Есть запрос, есть его результат на момент времени Х.
С ним можно работать.
V>Код синхронизации однократный для произвольных разных типов док-тов.
V>Всё-равно оперируемая схема строк БД зачитывается динамически.
Ну, тогда и с Аксессом разницы нет.
V>Раза в 2-3 только на совсем уж синтетических тестах в одном цикле.
V>А как более-мнее реальность, как начинаются развесистые графы объектов в памяти, так 10 раз аж бегом разницы по потребляемой памяти и быстродействию.
В типичных OLTP задачах нет никаких развесистых графов объектов в памяти. Если есть — то что-то не так с реализацией.
V>Ну я тебе давал уже реальные цифры по нейтивным системам.
V>Сотовые базы на узлах тоже работают аж бегом при самом жутком трафике из всех возможных.
Что такое "сотовые базы"? Это случайно не про роутеры на Эрланге рассказ?
V>Голая нейтивная конкатенация даёт примерно 3-5-тикратный прирост.
Хотелось бы посмотреть на результаты реальных замеров.
V>Но этого мало, мы же работаем через абстракции навроде StreamWriter, а там разница чудовищная по итогу выходит, более 20 раз.
А тут-то откуда?
V>Нейтивный парсинг HTTP-заголовков даёт примено столько же, в 3-5 раз и умножай это на более эффективный ввод/вывод в сравнении с дотнетными Stream.
Наверное, надо всё же складывать, а не умножать.
V>При применении всякой "полигональной" памяти, т.е. алгоритмов управления памятью, которые хорошо заточены именно под серверные задачи навроде вопрос-ответ — там еще +50% производительности прибавляй, т.к. управление памятью становится де-факто бесплатное от слова совсем.
Неужто можно инкремент поинтера обогнать?
V>Набор SQL-запросов у вас фиксированный, их "оптимизированные" версии можно нагенерить в офлайне, в кач-ве шага билда.
Ну, вот до этого у меня никак руки не доходят дописать типичный OLTP запрос и посмотреть, сколько там будет вариантов плана.
Есть существенные подозрения, что надо смотреть не в сторону офлайна, а в сторону рантайм-компиляции.
Просто большинство современных движков писалось в такую эпоху, когда встроить компилятор в приложение было малореально.
Сейчас нет никакой проблемы за миллисекунды получить из плана запросов его бинарную версию, используя коробочные технологии.
Тот же Microsoft предлагает писать триггеры на C# и компилировать их статически, вместо того, чтобы сделать банальный компилятор из T-SQL в MSIL и разогнать существующие базы без вложений труда.
V>Вот как раз периодически замеряем, стабильно примерно в 10 раз разница.
Между чем и чем?
S>>А на отдаче HTML сильно много не сэкономишь. Ну, может процентов 20% за счёт более агрессивного инлайна в клинических случаях.
V>Не так давно в местном плюсовом форуме соревновались в библиотеках форматирования текста.
V>Разница более 8 раз с традиционными STL-потоками iostream, а те работают быстрее дотнетных StreamWriter.
Ссылка бы помогла.
V>Нейтив — это нейтив.
V>Там любое серверное приложение сразу из себя автомат представляет (или набор автоматов), т.е. прямо начиная от самой низкоуровневой архитектуры. Ничего другое на серверной стороне смысла не имеет.
Для интересу можно сравнить архитектуру нативного Апача и нативного lightthpd или nginx. Чтобы понять, что не любое нативное приложение способно нормально работать. Ruki.sys никто не отменял.
V>Вот, еще и дотнет за тебя решает, как ты будешь коннекшены использовать.
V>А что один и тот же коннекшен можно делить м/у разными запросами, если из одного и того же потока — этого ты через дотнет, увы, не провернёшь. Это можно было через native client или возвращённый на днях к жизни OLEDB-драйвер:
V>https://blogs.msdn.microsoft.com/sqlnativeclient/2017/10/06/announcing-the-new-release-of-ole-db-driver-for-sql-server/
Это про MARS? Сомнительная фича. Для любителей "живых курсоров" и задрачивания сервера в режиме "N+1" аka master-detail.
V>Вроде, мы же уже выяснили, что ты был не в курсе про дефрагментацию индексов и деградацию быстродействия?
Неа. Мы пока что выяснили, что вы, коллега, полагали, что MyISAM в MySQL хранит индексы в том же файле, что и данные.
Про фрагментацию индексов мы ещё не разговаривали — в прошлый раз при моём уточняющем вопросе про "ресайз страницы" в MS SQL вы сослались на коллегу из курилки и сбежали из темы.
Я с удовольствием почитаю ваши очередные перлы про то, как "на самом" деле устроены B-tree индексы, и как "деградирует быстродействие" при "дефрагментации".
V>Мы про сценарий "склейки" сервака приложений и СУБД во всём этом топике обсуждаем.
V>Очередь запросов чудовищная в известных мне областях, для которых я подобную систему и предлагаю, собсно.
А, просто вы мечетесь, как заяц по огороду. В этой ветке я комментировал исключительно про неспособность никаких систем, кроме Акссеса, совместно работать с локальными и удалёнными данными.
Если хотите вернуться к in-proc/out-of-proc для высоконагруженного сервера, то можно поговорить и об этом.
V>Мы обкатали этот сценарий и показали его преимущество в GUI-приложениях.
Отож. Я прямо уж не знаю, что бы было с индустрией, если бы не вы.
V>В цикле.
V>И речь шла обо всём отображаемом наборе, а не вообще о всех данных в таблице.
Печалька. Ну, то есть клиппера вы всё-таки не видели. Жалко, у меня исходников не сохранилось. Дискетки столько не живут
V>Ты мне дай типизированную коллекцию, а не абстрактную.
Для чего?
V>В любом случае, коллекция выдаёт нетипизированные элементы и проверка их приведения тоже происходит в рантайм.
Конечно. И это делается ровно в одном методе.
V>Поэтому, типизированные коллекции были весьма популярны.
V>Настоящие, статически-типизированные.
V>В реальных Delphi-приложениях бывают произвольные коллекции.
V>В том числе писанные вовсе с 0-ля.
V>В большой системе таких коллекций больше, чем встроенных.
Ну вот у нас в проекте на сотню тысяч строк было три таких коллекции. На дельфи же не математику писали, а бизнес приложения.
V>Показана средняя скорость НЕ самого диска, а результатов у населения.
V>А там не факт, что тестируемая техника имеет PCIe 3.0, в пользовательском-то сегменте самая популярная до сих пор PCIe 2.0.
V>Но даже по твоей ссылке видно, что у некоторых пользователей бенчмарк даёт те самые 3.6 гига/с.
Повторюсь: maximum: 2,859. Результатов с 3.6 гига среди 20000 результатов не зарегистрировано.
А нас, пользователей RDBMS, интересует не этот максимум, а random 4k в mixed режиме. Где мы наблюдаем значительно более реалистичные 280 мегабайт в секунду. Не гига байт, а мега байт.
Память в рандом режиме всё ещё в сорок раз быстрее.
V>Покажи мне по твоей ссылке условия тестирования?
http://www.userbenchmark.com/Faq/What-is-sequential-read-speed/44
Можете скачать софтинку оттуда и проверить свою машину.
V>Продолжаем ликбез: на SSD-дисках любая относительно-длинная запись (длиннее строки хранения), даже про которую операционка рапортует как расположенную "в одной куче", де-факто "разбросана" по диску. SSD — это разновидность статической памяти, т.е. ей пофиг, насчёт в куче или не в куче, на физическом уровне там всё-равно обычный адресный доступ, как в оперативке.
Ухты! А чо ж тогда у него так различается скорость чтения в линейном режиме и покусочном? Там не всё так просто, как кажется.
V>>>Обрати внимание на графике на размер очереди запросов IO самого накопителя.
S>>Не вижу графика с размером очереди.
V>Надпись DQ=128 на графике — это длина очереди.
А, понятно. Ну вот, скажем, если сравнить очередь длиной в 64 с очередью длиной в 1, то ускорение всего в 4 раза. На вашей картинке при длине очереди в 128 намерили 800MB/s, но, поскольку кроме картинки, вы ничего не привели, то есть риск, что речь идёт о чистом чтении. Что в OLTP задаче не встречается.
V>>>Да хотя бы почему приложение на дельфях медленнее работает с базами данных при отображении в таблицах.
S>>Брр. Медленнее, чем что? С парадоксом дельфи работал просто прекрасно.
V>Медленнее при листании страниц.
V>Просто взять относительно большую выборку, схватить мышой бегунок на скролл-баре и погонять туда-сюда.
Ок, и почему же дельфи с Парадоксом будет работать медленнее, чем Access?
V>(блин, в каждом абзаце можно цокать и цокать языком)
V>В общем, 3-й FoxPro от 95-го года был уже графический.
V>А "окончательная" 5-й версия — от 97-го года.
V>Собсно с этой версии и пошла популярность FoxPro, на котором было разработано мильон GUI-приложух (последующие версии FoxPro от 5-го отличались не сильно).
У нас популярность фокспро началась задолго до 95го года. Большинство приложений было разработано в начале 90х на фокспро для ДОС, и использовалось вплоть до перехода на полноценные клиент-серверные решения.
Вот, например, ознакомьтесь с БЭСТ-4: http://best-trade.narod.ru/bestface.htm
Выпущен в 2000 году. Всё ещё никаких Visual Foxpro — банальный дос-режим, текстовый терминал, внутри — фокспро.
Возможно, в ваших кругах фокспро 3-5 кого-то и интересовали, но у нас его никто не пользовал. Поэтому рассматривать этот продукт я смысла не вижу.
V>Это я приводил для демонстрации, что наиболее эффективным способом работы с ISAM-базами было открытие навигируемого рекордсета по индексу. В этом случае чтение данных можно было производить прямо в операции отрисовки окна, без предварительного чтения. Так вот, недостаток FoxPro был в том, что он для отображения в таблице текущей страницы сначала должен был прочитать отображаемые строки, что создавало подтормаживания GUI.
Не уверен, что недостаток — именно в этом. Потому что способа отобразить строки, не читая, я не знаю. Или имеется в виду возможность успеть дёрнуть мышкой курсор ещё до того, как отрисуются все строки, и сэкономить 250мс на ожидании подгрузки?
V>ISAM вполне себе выбор для сервера приложений в трехзвенке.
V>Только не stateless псевдотрёхзвенке, как в случае HTTP-фронтенда, а настоящего stateful.
Чисто уточнить: здесь под ISAM подразумевается прямое управление курсорами? Все вот эти вот locate и seek? Вместо декларативного описания запросов, я ничего не перепутал?
V>Ну блин, как речь об ISAM, так ты проваливаешься в область сетевого доступа к файлам.
V>Это какой-то пипец.
V>При том, что мы даже разобрали My SQL, где в одной из его конфигураций над ISAM работает полноценный СУБД-процесс с исключительным доступом.
Ага. И это — та самая конфигурация, в которой невозможно даже сказать rollback tran, если по пути мы нарвались на нарушение ограничения.
V>При том, что любая среда программирования несла с собой справку?
Ага. Справку по форме 086-У. Вот, к примеру, с MSVS6.0 шла документация по WinAPI. По вопросу "работа с ком-портом" — ровно одно упоминание в CreateFile: что можно открыть файл с именем "COM1:" — и будет щасьте.
Как настраивать скорость передачи, биты контроля чётности — ничего. Нуль. Как проверить, пришли ли данные — угадывай. Пробовал открывать — щастья не было. Вроде даже иногда что-то читалось, но почему-то с пропусками и перебоями.
Тут справкой не отделаешься — нужна нормальная литература, с объяснением, как и что работает. А такого не было. Про ДОС были и книжки, с детальным описанием, как вешаться на прерывания, что куда писать, что откуда читать, и с примерами простейших программ.
V>Хотя, если уж по-справедливости относительно тех лет, то больше речь шла о доступе к машинному времени с нужной версией ОС.
V>Так-то получить машинное время под ДОС было проще, угу.
У меня было бесконечное машинное время, и ДОС, и винда. Вот только интернета не было. Поэтому приходилось пользоваться тем, что есть, и что работает.
V>Вопрос в том — можно ли делать move назад или устанавливать произвольную запись текущей.
V>https://docs.microsoft.com/en-us/sql/ado/reference/ado-api/move-method-ado?view=ssdt-18vs2017
V>А так же — курсор статический или динамический, если можно навигировать по записям туда-сюда.
Под капотом — всё равно операции чтения/записи.
V>Я примерно понимаю, о чём ты, но это ходьба по-кругу.
V>- получается, что страницы shared-memory ты предлагаешь использовать сугубо как транспортные, то бишь аргументы "зато нет копирования" фтопку, бо копирование будет дважды — на стороне сервака на страницу и на стороне клиента из страницы;
Ох-хо-хо. Кто-то кого-то не понимает.
Вот у нас есть кусок клиентского кода, допустим, вот такой:
rs.MoveLast()
var s = rs.ReadString(12) // reading the field #12
Это я предполагаю, что у нас есть способ читать данные типизированно, а не вытаскивать VARIANT с последующим приведением.
Что у нас будет под капотом? Ясен хрен, что у рекордсета внутри — какой-то буфер. Рекордсет не читает одну запись. Он читает сразу, скажем, полмегабайта записей, включая последнюю. Если мы говорим об in-proc сервере, то это будет буфер файла. Возможно, как в MySQL, это будет отображение файла на память; возможно, там внутри будет прямо Read() в сырой массив.
Вызов операции чтения приведёт к проверке метаданных, поиску смещения текущей записи, разбору её заголовка в поисках смещения данных запрошенного поля, и конверсии. Потому, что внутри у нас поле хранится в Win1252 или UTF-8 или ещё как-то, а читаем мы его в UCS-2. Даже если бы мы вернулись в каменный век и сказали, что мы возвращаем сырые данные прямо в формате хранения, то пришлось бы внутри ReadString() делать nstrcpy, т.к. у нас даже 0-terminatоr не хранится.
А что будет в случае с Shared Memory? Да всё то же самое, только буфер заполняется другим процессом, а не системой.
Следующее чтение случится тогда, когда позиционирование рекордсета попробует выйти за пределы буфера — тогда у нас снова подкачается буфер, т.к. гонять данные по 4 байта очень дорого — что с диском, что с соседним процессом.
В обоих случаях под капотом происходит переключение контекста.
И это мы предполагаем совершенно безумную идею, что клиенту интересно разбираться с устройством таблиц и индексов. То есть он работает прямо с теми данными, которые хранятся.
А на самом деле, клиент выполняет запрос в духе
select @docId, Commodity, case when Amount-RunQty>0 then Quantity else Amount-RunQty+Quantity end as moveQty, id from
(select oi.Commodity, oi.Amount, coalesce(RunQty, 0) as RunQty, coalesce(Quantity, 0) as Quantity, remainders.id from
OrderItems oi left join
(select id, Commodity, Quantity, (sum(Quantity) over(partition by Commodity order by ArrivalDate asc)) as RunQty from Consignments) remainders
on oi.Commodity = remainders.Commodity and remainders.RunQty - Quantity < oi.Amount) itemRemainders
И получает на выходе рекордсет, который ни к какому файлу не относится. Поэтому сервер заботливо готовит буфер на своей стороне и говорит клиенту: "готово".
Тот забирает буфер и начинает с ним работать (т.е. читать данные). Идея "биндить курсор к GUI" работает только в одном малоинтересном сценарии: "редактирование справочников", где элементарная операция волшебно совпадает со строкой таблицы.
V>Мне всё еще требуется объяснять, почему out-of-proc существенно затратней?
Конечно требуется. Пока что вы ничего не обосновали, кроме "да в девяностые все это знали".
V>Я всё что угодно обыгрываю по производительности прямо замерам лабораторий Интел.
V>Работа у меня такая.
Да-да, а ещё вы очень скромный.
V>Они отключают шедуллинг ОС этого механизма, но не отключают сам механизм.
Чего?
V>Именно под задачи СУБД из виндов торчит АПИ навроде ReadFileScatter/WriteFileGather.
Ухты! Как интересно. Мне вот казалось, что эти АПИ совсем для другого.
Может, проиллюстрируете мне, как эти АПИ помогут мне прочесть с диска набор из десятка страничек, разбросанных по файлу?
V>Я нагуглил и данные тебе уже дал.
Ну, приличные люди дают не только картинку, но и ссылку на статью, в которой она упомянута.
V>>>А, может, ты забыл, что операции записи в shared-память провоцируют исключения ОС?
S>>Хуже — я про это даже не знал. А где прочитать про эти мифические исключения? Мне просто непонятно, для чего они могут быть нужны. Ведь shared memory ничем от обычной не отличается.
V>Shared-memory в Windows — это один из способов IO для файлов.
V>Самый эффективный способ для того самого IO для файлов, угу.
V>Литературы по отображаемым файлам — полно.
V>RTFM!
Ну вот нигде из того, что я читал, нету никаких упоминаний про то, что запись в shared-memory будет провоцировать какие-то исключения. Вот я и хочу, чтобы вы мне популярно объяснили, как это работает. Ну, вот, допустим, у меня "сервер" хочет отдать 64 килобайта данных "клиенту", и с этой целью заполняет буфер в shared memory путём банального цикла:
for(i=0;i<16384;i++)
buffer[i] = i;
Сколько у нас произойдёт "исключений ОС"?
Изменится ли это количество, если мы вместо shared-memory буфера будем использовать "обычную" память?
V>На такой технике и таких скоростях и это прокатывало, и?
Не, не прокатывало. Там практики code review не было, но ради такого случая его провели, автора — уволили.
V>Или невозможности твоей схемы "буфер1 заняли, освободили буфер2 и так по-очереди" для shared memory, при локальном out-of-proc и при живом динамическом курсоре.
V>Да не, у "живого" курсора именно что амба, даже если связь восстановили.
"Живой" курсор — это вообще фикция. Классическая дырявая абстракция.
Системы, написанные "программистами живых курсоров" в девяностых годах до сих пор масштабируют путём запуска в терминальной сессии на супермегасервере.
И считают, что двести активных пользователей — это типа ого-го как много.
V>Просто открываешь forward-only и читаешь данные, кешируя их локально.
Воот. Потому что в нормальной распределённой среде нет такого понятия, как "живой курсор". Есть запрос, есть его результат на момент времени Х.
С ним можно работать.
V>Код синхронизации однократный для произвольных разных типов док-тов.
V>Всё-равно оперируемая схема строк БД зачитывается динамически.
Ну, тогда и с Аксессом разницы нет.
V>Раза в 2-3 только на совсем уж синтетических тестах в одном цикле.
V>А как более-мнее реальность, как начинаются развесистые графы объектов в памяти, так 10 раз аж бегом разницы по потребляемой памяти и быстродействию.
В типичных OLTP задачах нет никаких развесистых графов объектов в памяти. Если есть — то что-то не так с реализацией.
V>Ну я тебе давал уже реальные цифры по нейтивным системам.
V>Сотовые базы на узлах тоже работают аж бегом при самом жутком трафике из всех возможных.
Что такое "сотовые базы"? Это случайно не про роутеры на Эрланге рассказ?
V>Голая нейтивная конкатенация даёт примерно 3-5-тикратный прирост.
Хотелось бы посмотреть на результаты реальных замеров.
V>Но этого мало, мы же работаем через абстракции навроде StreamWriter, а там разница чудовищная по итогу выходит, более 20 раз.
А тут-то откуда?
V>Нейтивный парсинг HTTP-заголовков даёт примено столько же, в 3-5 раз и умножай это на более эффективный ввод/вывод в сравнении с дотнетными Stream.
Наверное, надо всё же складывать, а не умножать.
V>При применении всякой "полигональной" памяти, т.е. алгоритмов управления памятью, которые хорошо заточены именно под серверные задачи навроде вопрос-ответ — там еще +50% производительности прибавляй, т.к. управление памятью становится де-факто бесплатное от слова совсем.
Неужто можно инкремент поинтера обогнать?
V>Набор SQL-запросов у вас фиксированный, их "оптимизированные" версии можно нагенерить в офлайне, в кач-ве шага билда.
Ну, вот до этого у меня никак руки не доходят дописать типичный OLTP запрос и посмотреть, сколько там будет вариантов плана.
Есть существенные подозрения, что надо смотреть не в сторону офлайна, а в сторону рантайм-компиляции.
Просто большинство современных движков писалось в такую эпоху, когда встроить компилятор в приложение было малореально.
Сейчас нет никакой проблемы за миллисекунды получить из плана запросов его бинарную версию, используя коробочные технологии.
Тот же Microsoft предлагает писать триггеры на C# и компилировать их статически, вместо того, чтобы сделать банальный компилятор из T-SQL в MSIL и разогнать существующие базы без вложений труда.
V>Вот как раз периодически замеряем, стабильно примерно в 10 раз разница.
Между чем и чем?
S>>А на отдаче HTML сильно много не сэкономишь. Ну, может процентов 20% за счёт более агрессивного инлайна в клинических случаях.
V>Не так давно в местном плюсовом форуме соревновались в библиотеках форматирования текста.
V>Разница более 8 раз с традиционными STL-потоками iostream, а те работают быстрее дотнетных StreamWriter.
Ссылка бы помогла.
V>Нейтив — это нейтив.
V>Там любое серверное приложение сразу из себя автомат представляет (или набор автоматов), т.е. прямо начиная от самой низкоуровневой архитектуры. Ничего другое на серверной стороне смысла не имеет.
Для интересу можно сравнить архитектуру нативного Апача и нативного lightthpd или nginx. Чтобы понять, что не любое нативное приложение способно нормально работать. Ruki.sys никто не отменял.
V>Вот, еще и дотнет за тебя решает, как ты будешь коннекшены использовать.
V>А что один и тот же коннекшен можно делить м/у разными запросами, если из одного и того же потока — этого ты через дотнет, увы, не провернёшь. Это можно было через native client или возвращённый на днях к жизни OLEDB-драйвер:
V>https://blogs.msdn.microsoft.com/sqlnativeclient/2017/10/06/announcing-the-new-release-of-ole-db-driver-for-sql-server/
Это про MARS? Сомнительная фича. Для любителей "живых курсоров" и задрачивания сервера в режиме "N+1" аka master-detail.