Re[80]: MS забило на дотнет. Питону - да, сишарпу - нет?
От: vdimas Россия  
Дата: 01.10.21 20:28
Оценка:
Здравствуйте, Sinclair, Вы писали:

V>>А что тут нового?

V>>Там как в любом другом наборе ресурсов и очередей к ним.
S>А что мы считаем ресурсом?
S>Если мы делаем классический блокировочник, то у него минимальная гранулярность блокировки — 1 строка.

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


S>То есть мы на select — запрос, который сканирует 50% таблицы с миллионом записей, последовательно захватываем и отпускаем 500000 блокировок.


База сама решает, как лучше заблокировать таблицу.
При скане таблицы чаще блокируется вся таблица (но есть хинты, разрешающие не блокировать таблицу при скане, 1C, например, активно их использует при зачитке справочных таблиц).
При скане индекса — индекс целиком.

Различают RO и RW блокировки.

Учитывая, что виды блокировок и их гранулярность находятся в строгой иерархии, я немного не понимаю суть твоих вопросов.
Что ты хочешь узнать?


S>На пальцах — цикл сканирования выглядит так:

S>
S>foreach(var candidateRow in table.Index1.IndexSeek(predicate.IndexPart))
S>{
S>   lock(GetRowLock(candidateRow))
S>   {
S>     if(predicate.ResidualPart(candidateRow))
S>       yield return selector(candidateRow);
S>   }
S>}
S>


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


V>>Эээ, тормоза на блокировках зависят от частоты конфликтов квадратично.

S>Даже в отсутствие конфликтов блокировки отжирают время.

В отсутствии конфликтов — одна интерлокед-операция на таблицу для скана таблицы.
Считай, бесплатно.


S>Вместо быстрого цикла с телом типа table[rowNumber].Slice(fieldOffset, fieldLength), которое при удаче вообще сворачивается в пару ассемблерных инструкций, у нас на каждой итерации начинается беготня по таблицам блокировок.

S>Интуитивно кажется, что эта беготня имеет примерно тот же порядок стоимости, что и интерпретация выражений вроде GetFieldValue(rowPointer, fieldId).

Выше уже объяснил, почему это не так.


V>>Прикинь, уменьшение времени исполнения заявки в системе из одной машины вдвое равно масштабированию этой машины в кластер на 4 узла.

V>>(это если считать, что сам кластер ничего не стоит с т.з эффективности, т.е. кластер сферический в вакууме)
S>Ну, вот у меня пока такое понимание, что основные задержки обработки "заявки" в современных трёхзвенках — это трипы между апп-сервером и СУБД.

Да.
И особенно забавен тот факт, что намного раньше масштабируют сервер приложений, а не СУБД, к которой множество узлов кластера сервера приложений обращаются конкурентно.
Разве такое положение вещей не наводит на необходимые мысли?


S>Компиляция — штука хорошая, но её эффект заранее трудно оценить именно потому, что не получается сделать из плана запроса код, сравнимыый с каноническим while(p*++=q*++);.


План запроса в любом случае оперирует готовыми предкомпилёнными "кубиками".
Речь о грануляции этих "кубиков".


S>Ну, вот мне сначала казалось, что компиляция даст офигенный буст к производительности DBMS. А сейчас я вижу некоторые ограничения, которые на первый взгляд будут замедлять исполнение кода примерно на десятичный порядок по сравнению с компилируемым кодом, который шарашит по "голым" данным, без оглядки на isolation и durability.


Это всё сводится к очередям заявок СМО.
Пока мест не существует другого механизма для описания происходящего.


S>Это сильно ухудшает производительность сканирования — вместо тупого обращения по смещению pageNo*pageSize, нужно лезть в bufferManager.getPage(pageNo), который даже на happy path добавляет лишнюю косвенность.


Косвенность на страницу и косвенность на поле — немного разные вещи.
Косвенность на страницу "размазывается" на стоимость обработки многих хранящихся на странице записей.


S>Поэтому MMF будут уместны только для mostly-read key-value storage, где как правило 1 транзакция == 1 изменение, а чтения доминируют над записями.


Мой подход в первейшую очередь отталкивается от того, что трафик чтения серьезно превалирует над трафиком записи, бо в случае записи в базу компиляция всего и вся в суровый нейти не даст порядка прироста производительности. Просто при записи чаще всего происходит обязательное сначала чтение-поиск (в т.ч. при проверке целостности уникальных индексов/ключей), это надо держать в голове. ))


V>>На своей заднице испробовал когда-то, да еще на тормознутой технике конца 90-х — начала нулевых, когда любые эффекты были ну уж слишком хорошо заметны.

S>Вот это как раз странно. Потому что при наличии уместных индексов, уменьшение рабочего объёма в N раз сокращает время операции на константу ~ log(N).

А общую эффективность в многопользовательской среде поднимает в квадрат раз от этой константы.

И эта, в суррогатых ключах тех же справочных данных и при нормальной статистике обращение к записи стоит O(log(N)) только при очень большом N, а на практике там пару ветвлений, а затем тупо смещение на странице индекса. Мы же недавно обсуждали B+ деревья, так вот, листья "знают", последовательный индекс в них или нет — на то она и статистика в индексе, что ведёт учёт "островков" данных.

Т.е., "законный" O(log(N)) будет при отсутствии всякой статистики.


S>Можно ли из полученных результатов делать какие-то выводы про производительность выполнения SQL кода в режиме интерпретации vs в режиме компиляции?

S>Нет, нельзя. Ну, то есть понятно, что медленнее от компиляции код уже не станет. А вот насколько он станет быстрее — это вопрос.

"Самописные" базы показывали ускорение на пару порядков еще в первой половине 90-х.
Такие базы писались для неконкурентного чтения-записи, обслуживались заведомо предкомпилённым кодом, т.е. АПИ такой базы давало заранее известный набор обслуживаемых запросов.

Я тщательно крутил одну из тогдашних бухгалтерий на DOS (текстовое "оконное" приложение) с собственным неконкурентным компиллируемым движком БД — с тогдашними СУБД на той технике сравнивать было бесполезно. Эта бухгалтерия была входу в нашем городе примерно до 95-96-х годов (вот этот человек автор, тогда 30+ ему было: https://companies.rbc.ru/id/1149204047024-ooo-irbis/, считался гением IT в нашем городе, занимался нацчными исследованиями в области IT, пока не ушел из ВУЗ-а), в общем, оно было востребовано пока 1С не начала пожирать всех, да и вообще, пока Windows окончательно не вытеснила DOS.


S>Сколько будет стоить компиляция — тоже вопрос, от которого зависит ответ на более интересный вопрос "при каких условиях динамическая компиляция выиграет у интерпретации".


Тут согласен, но это опять умозрительное на далёкое будущее.
Пока мест JIT-компиляция работает не на таком уровне, а движки баз данных не генерят код, пригодный для JIT.


S>Похожий вопрос — "при каких условиях статическая компиляция выиграет у динамической".


Это если в наличии есть динамическая компиляция.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.