Здравствуйте, vdimas, Вы писали:
V>>>Изначальная задача SQL была совсем другая. CK>>Это какая? V>Консольные запросы от человека в интерактивном режиме.
Почитай оригинальную статью Кодда.
Можешь перед этим почитать что-нибудь про CODASYL и Network Model, чтобы понять как оно было до SQL. То что SQL был расчитан на секретарш — это какой-то странный миф, непонятно откуда взявшийся. Ес-но статья не про SQL, а про реляционную модель, SQL появился позже, вместе с System R. Ни про каких секретарш Чемберлин и Бойс тоже не писали, если чО. То что запросы должны в интерактивном режиме вводиться, так это и сейчас так. Зачем мне не интерактивный язык запросов? Попробуй подергать Elasticsearch запросами через curl, оцени удобство :D
V>>>"Логика приложения" тут не при чём, SQL сегодня участвует сугубо в транспортном уровне. CK>>Ну это кто как приложения разрабатывает. V>Все так разрабатывают.
0 аргументов, тут ты высказываешь крайне сомнительную точку зрения, тебе и доказывать
V>Оно и так есть — вьюхи и хранимки на стороне базы.
В хранимки не принято класть сложную логику application/business logic/domain и все такое. Сложная логика должна жить в коде приложения.
V>Как "так"? V>Сформулируй внятнее.
Впихивают логику приолжения и domain/application знания в БД.
V>Практически любое статически-скомпиллированное приложение обрабатывает те самые "динамические данные".
Компиляторы не генерируют программы JFYI.
V>Ты ветку читал? ))
Нет. Только некоторые комментарии, ничего похожего на обоснование этой твоей идеи не встретил.
V>Ну вот почитай, а то пошли уже повторения.
Если ты дашь ссылку на комментарий, в котором эта идея доступно изложена, буду рад ознакомиться.
CK>>Такое в статике сделать нельзя. V>Не верно.
Ты думаешь статически создать план под любой возможный запрос и любое возможное распределение данных?
CK>>Компилятор не выбирает алгоритм, он просто оптимизирует. V>В чём заключается возможность оптимизации?
Ты сейчас не про определенный компилятор говоришь, а про гипотетическую возможность?
V>Ну я пока мест пытаюсь заставить собеседников разобраться, что именно происходит при планировании выполнения запроса. V>Потому что на таком уровне как говоришь ты — это беспредметный разговор.
Я разработчик БД (одной конкретной, довольно известной, колумнарной аналитической БД) и я знаю как работает планировщик запросов. Что тебе про э то рассказать?
V>Может и часто делает именно так. V>Не перестраивает динамически, но динамически выбирается одна из уже готовых оптимизированных веток. V>Или в один и тот же цикл происходит заход в динамически выбираемую точку входа.
Современные компиляторы так не делают. Точнее они могут выбирать ветку, скажем, если компилятор векторизует цикл, там обязательно будет ветка для не случая когда данные не выровнены и ветка для случая когда данные выровнены, но каждая ветка будет делать одно и то же, только с использованием разных инструкций. Компилятор не превратит твой внутренний цикл в поиск в хэш таблице или что-нибудь в этом духе.
CK>>Но ты можешь это обойти, начать собирать информацию о данных (гистограммы, скетчи и тд) и выбирать ту или иную реализацию динамически, во время исполнения. Если так сделать, то получится примитивный планировщик запросов БД.
V>Верно. V>Только с сохранением типизации на обеих концах транспорта и с выкидыванием до половины ненужных затрат на обеих концах системы.
Здравствуйте, chaotic-kotik, Вы писали:
V>>>>Изначальная задача SQL была совсем другая. CK>>>Это какая? V>>Консольные запросы от человека в интерактивном режиме. CK>Почитай оригинальную статью Кодда.
А что ты в ней не понял?
CK>Можешь перед этим почитать
Можешь прямо сейчас сходить до лесу.
CK>То что SQL был расчитан на секретарш — это какой-то странный миф, непонятно откуда взявшийся.
Это факт.
CK>Ес-но статья не про SQL, а про реляционную модель, SQL появился позже, вместе с System R.
Вот и молодец.
Сам намусорил, сам же прибираешься.
V>>>>"Логика приложения" тут не при чём, SQL сегодня участвует сугубо в транспортном уровне. CK>>>Ну это кто как приложения разрабатывает. V>>Все так разрабатывают. CK>0 аргументов, тут ты высказываешь крайне сомнительную точку зрения, тебе и доказывать
Доказываю списком либ, где SQL идёт в транспортном слое: начиная от ODBC/OLEDB/ADO, заканчивая "высокоуровневыми ORM".
Доказательство окончено.
V>>Оно и так есть — вьюхи и хранимки на стороне базы. CK> CK>В хранимки не принято класть сложную логику application/business logic/domain и все такое.
Это потому что язык уродский, поэтому на ём стараются не писать, по-возможности.
И всё-равно логику в базу часто кладут, бо выхода порой НЕТ.
CK>Сложная логика должна жить в коде приложения.
SQL-код на стороне базы — тоже часть приложения.
Просто самая стрёмная по состоянию на сегодня.
Об этом и речь в этой выделеной подветке.
CK>Впихивают логику приолжения и domain/application знания в БД.
Именно так.
В сами данные, в диапазоны значений, в ограничения целостности, в прочие внешние ключи, триггера и т.д. и т.п.
V>>Практически любое статически-скомпиллированное приложение обрабатывает те самые "динамические данные". CK>Компиляторы не генерируют программы JFYI.
Сдаюсь. Удеал.
CK>Нет. Только некоторые комментарии, ничего похожего на обоснование этой твоей идеи не встретил.
Ну нет, так нет. До встречи в следующей жизни. ))
Re[22]: В России опять напишут новый объектно-ориентированны
Здравствуйте, vdimas, Вы писали:
V>20-30 раз. V>Смирись. ))
Я скорее поверю статье о NASDAQ, чем рассказам форумного болтуна.
V>Результат в 30 млн tpmC был показан ораклом на каком-то совершенно дичайшем sun-кластере.
Отож. V>А на сравнимой не кластерной технике (обычные серваки на ксеонах) они все ноздря в нозрю ходят: V>Машинка — HP ProLiant DL370 G6 V>Oracle Database 11g — 631766,00 V>Microsoft SQL Server 2005 — 661475,00
Ну и что? Мы говорим о максимальных мощностях, а не об "обычных серваках на ксеонах". Если ограничиться 80286, то вообще всех порвёт FoxPro. V>Возьми свой ноут, который на батарейках, поставь Оракл, MySQL и сравни.
Предположение о том, что результаты замеров на ноуте можно масштабировать на "дичайшие sun-кластеры" — это и есть нубство.
На ноуте и SQLite будет показывать отличные результаты. Тем не менее, никто в здравом уме не возьмётся строить решения задач типа TPC-C на SQLite. V>За пол-ляма в сек "просто запросов" MySQL перешагнул уже относительно давно на относительно скромном оборудовании.
Меня не интересуют "просто запросы". Интересуют результаты нормальных бенчмарков. Вот когда MySQL освоит TPC-C — велком, пообсуждаем.
А пока что речь идёт о том, как бы он круто выиграл забег, если бы ему дали.
V>Реальные цифры привёл я чуть выше. V>А твоими цифрами, как обычно, только детей пугать. ))
Ну, мы же сравниваем биржевую торговлю с учётными системами, нет? Или там весь NASDAQ бегает на "обычном серваке на ксеонах"?
Если нет, то нехрен и RDBMS ограничивать.
V>Это при малом трафике.
(facepalm) V>Опять же брехня. ))
(facepalm)
V>Миллион транзакций в сутки — это тебе нужно откопать совсем старый ноут на батарейках, который не справился бы.
(facepalm)
V>Слушай, ну на кого это опять рассчитано? )) V>Ну сколько ж веревочке не виться, а за конец схватят. V>По ссылке находится описание: V>1. ввода заказа (просто ввода, а не свершения с соответсвующими движениями по складу) V>2. ввода платежа, для хоть какого-то усложнения добавили какую-то синтетическую нагрузочную логику. V>3. А вот это вообще пестня: V>
V>The Order-Status business transaction queries the status of a customer's last order. It represents a mid -weight read —
V>only database transaction with a low frequency of execution and response time requirement to satisfy on -line users.
И? Всё, на этом дневной лимит чтения текстов закончился? То есть про delivery и stock-level не удалось прочесть?
Транзакции типа order-status введены для того, чтобы при тесте не жульничали — иначе можно просто не записывать статусы ордеров при модификациях. То же самое — stock-level. V>)) V>Я давно знаю, что некоторые темы из IT для тебя беспредметны. V>Напоминать было не обязательно. V>Просто ты пытаешься рядом рассуждать о "недостатке декомпозиции в SQL" (С) не понимая принципов построения языков этого поколения. V>И тем более не понимая оксюморона ситуации с генерацией предложений этого языка из более низкоуровневых языков.
Продолжается беспредметное умничание. Кого интересует моё непонимание? Тут мы видим твою неспособность объяснить, не более того.
S>>Ну почему же единственная. Вон, NASDAQ как-то обходится без неё. V>Ценники недемократические. V>Считай, что для тебя этого нет, как и суперкластера Sun из того бенчмарка.
Опять смешно. Ценник интересует в терминах одной транзакции. Вот, допустим, я хочу построить систему обработки заказов типа Амазон. У меня есть норматив прибыли с каждого заказа. Он не жёсткий, тем не менее есть понятия об ARPU и прочих средних значениях. Допустим, я зарабатываю $1 на каждом заказе — это немного для обычного рынка розничной торговли.
Итак, я зарабатываю $1 на каждом заказе. Вот у меня суперкластер стоимостью $30M. За какое время он окупится? Для этого в результатах тестов есть специальная колоночка: Price/Perf. Для конкретно этого результата там записано 1.01.
То есть наш кластер окупится примерно за 1 минуту эксплуатации.
Ок, допустим, я торгую чем-то очень недорогим — приложениями в АппСтор, и маржа у меня всего лишь 1 цент на транзакцию. За какое время окупится кластер? Полтора часа.
Ну, и где здесь "недемократические ценники"?
А если нагрузка в полмиллиона транзакций в секунду не планируется — то можно обойтись и значительно более скромной аппаратурой, и выжимать такты на "статика против динамики" не потребуется.
V>Аналог. В некоторых языках пошли на хитрость, сумев при почти таком же синтаксисе превратить SQL-запросы в полноценные выражения ФП-подобного языка. Но далее уже идёт строгая типизация и прочие плюшки развитого языка.
Это мы мне рассказываем про Linq? Если есть ещё что-то интересное — пиши.
V>>>У меня больше было, под 5 тыс, и? S>>И как это укладывается в схему "статической компиляции" и выбора планов запросов?
V>Примерно так же, как "раздутый" на шаблонах код потом "склеивается" в процессе оптимизации при линковке. V>Тривиальный пример — ты там приводил что при последующей проекции из произведения может целая таблица улететь, мол, ого какая оптимизация. V>Так вот, вся эта шелуха в статике совсем хорошо разруливается, освобождая динамику. V>И такой шелухи много. V>Современные оптимизаторы отслеживают не только типы, они отслеживают жизненный цикл данных, принимают решения по трансформации графа операций с данными и т.д.
А статистику они откуда берут? Откуда они знают, что при одном значении параметра надо сканировать один индекс, а при другом — другой?
V>Это с учётом библиотечных. V>Там же сразу появляются мощные библиотеки, т.е. всё по-взрослому. V>А писанных тобой лично процедур — резко сократилось бы. V>Так у меня в любой базе жил еще заметный утилитно-библиотечный слой.
Ну да, примерно так и есть. Хотя чётко отделить кто пишет какой слой скорее всего не получится. V>У меня сие "осознание" произошло еще до 97-го года.
А выглядит так, что оно появляется ровно в процессе этого разговора. Причём очень медленно, потому что кое-то всеми силами избегает конкретных утверждений. Вместо "в языке Scala есть вот такая штука" пишется "есть некоторые языки, которые менее ограничены кое-в-чём, по сравнению с кое-какими другими языками". Понятно, что на вот таких полунамёках построить полноценную дискуссию затруднительно. V>Просто это первый раз на моей памяти, когда на эти темы народ соглашается просто поговорить. V>Сам такой разговор в году эдак 2005-м был просто невозможен.
V>В общем, тут декомпозицией не отделаешься, тут дизайн языка с 0-ля менять надо.
Вот тут всегда возникает дилемма: слишком далёкий от привычного язык даст нулевую заинтересованность. Слишком близкий — даёт мало толку. Языки изобретать тяжело (по крайней мере, хорошие).
Опять же — как делать: по языку для каждого слоя, или один на всех? В Smalltalk был один язык на всё, но Gemstone с точки зрения DBMS — говно. То, что они называют "индексами" приличные люди за столом не упоминают. Основной язык слишком императивный.
В современном мейнстриме мы имеем либо вавилон из JS+Java+SQL, когда каждую фичу должно делать три разработчика плюс два тестера плюс отдельный менеджер, чтобы следить, чтобы все края совпали, либо JS everywhere с феерически неэффектиывым бэкендом и базой данных.
V>Просто лично я за такой язык, который допускал бы и статическую компиляцию с максимумом проверок/ограничений/оптимизаций. V>Но, если потянуть за эту ниточку — там вытягивается слишком много кардинальный отличий от нынешних мейнстримовых практик.
Чтобы штука заработала, надо, чтобы она окучивала целую вертикаль — вот прямо от клиента и до сервера. Иначе — будь любезен, соответствуй общепринятым стандартам. Я об таком в свободное время фоном думаю, но во-первых, уделяю мало времени, во-вторых, не уверен, что это всё ещё актуально. Грубо говоря, непонятно, нужны ли ещё людям те приложения, которые я себе воображаю. TPC-C вышел из моды потому, что уже лет 15 никто не пишет учётные системы.
V>>>Мде? А НС и Ко (включая основной его ник) на этом же сайте регулярно доказывают, что ORM летает как трофейный мессершмит, что все эти затраты "не видны и под микроскопом при обращении к базе". S>>Он имеет в виду другие ОРМ, чем я тут упомянул. V>Так что не так в Датском Королевстве?
Нет хороших фреймворков и вообще понимания, что и как должно делаться. Глобально — потому, что люди, выделяющие финансирование, катастрофически некомпетентны. Им показывают прототипы из одной странички, за которыми стоит база из 5 строчек. Когда начинается нормальная нагрузка — то либо проект дохнет (если не успевает принести денег), либо под него нанимаются мега спецы, которые способны собрать кастом билд MySQL и прикрутить статическую оптимизацию к PHP. Людям такого уровня "библиотеки" и "фреймворки" вообще не нужны — они сами могут компилятор сварганить.
А начинающие выбирают инструменты, которые позволяют "через полчаса в продакшн", а не те, которые позволяют за день написать код, который после пилота смасштабируется в 10000 раз по объёму и нагрузке. V>Почему rsdn тормозит? ))
RSDN для своего объёма и железа просто летает. При этом у него внутри как раз MS SQL + linq2db.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[23]: В России опять напишут новый объектно-ориентированны
Здравствуйте, Sinclair, Вы писали:
V>>Машинка — HP ProLiant DL370 G6 V>>Oracle Database 11g — 631766,00 V>>Microsoft SQL Server 2005 — 661475,00 S>Ну и что? Мы говорим о максимальных мощностях
Мы говорим о ситуации в современом IT.
S>а не об "обычных серваках на ксеонах"
А в современном IT 99% всех серваков — они "обычные", на ксеонах.
S>Если ограничиться 80286, то вообще всех порвёт FoxPro.
Это не современное IT.
V>>Возьми свой ноут, который на батарейках, поставь Оракл, MySQL и сравни. S>Предположение о том, что результаты замеров на ноуте можно масштабировать на "дичайшие sun-кластеры" — это и есть нубство.
Я это не предполагал.
Я предлагал посмотреть на ходовые сценарии и что в них не так.
S>На ноуте и SQLite будет показывать отличные результаты.
Не будет.
V>>За пол-ляма в сек "просто запросов" MySQL перешагнул уже относительно давно на относительно скромном оборудовании. S>Меня не интересуют "просто запросы". Интересуют результаты нормальных бенчмарков.
Зависит от сценариев.
Когда надо в основном только отдавать данные, то MySQL на современной технике практически вне конкуренции.
S>А пока что речь идёт о том, как бы он круто выиграл забег, если бы ему дали.
Дык, он и выиграл давным давно.
Чуть менее чем весь современный веб опирается на MySql в бэкенде.
V>>А твоими цифрами, как обычно, только детей пугать. )) S>Ну, мы же сравниваем биржевую торговлю с учётными системами, нет? Или там весь NASDAQ бегает на "обычном серваке на ксеонах"?
На нескольких обычных, обслуживающих непересекающиеся рынки.
Потому что важен не только и не столько throughput, сколько latency.
А приличные цифры latency сегодня дают ни в коем случае не кластеры, а хорошо вылизанные "единичные" серваки.
S>Если нет, то нехрен и RDBMS ограничивать.
Но ведь нет. ))
На этом кластере при его чудовищной througput показана одна из самых плохих latency — порядка 0.1 сек.
Это только в мусорку по современным реалиям.
V>>Просто ты пытаешься рядом рассуждать о "недостатке декомпозиции в SQL" (С) не понимая принципов построения языков этого поколения. V>>И тем более не понимая оксюморона ситуации с генерацией предложений этого языка из более низкоуровневых языков. S>Продолжается беспредметное умничание. Кого интересует моё непонимание? Тут мы видим твою неспособность объяснить, не более того.
Так я ХЗ с какого уровня начинать давать, ты же не определил себя никак.
Можно начать с базы — языки 3-го поколения построены на простой базе, но мощных ср-вах комбинирования этой базы.
Языки 4-го — наоборот. Имеют мощную базу при слабой возможности комбинирования.
Считается, что одно выражение языка 4-го поколения и так уже достаточно высокоуровневое, т.е. покрывает собой тысячи и/или десятки тысяч строк кода на языках третьего поколения.
Но это представления из 80-х годов. Весьма радужные, как можно заметить, оборачиваясь назад.
Сегодня уже понятно, что наиболее удобны те языки (причём из 3-го поколения), которые обладают "хорошей выразительностью".
Т.е. по мере реализации всё более высокоуровневых конструкций исходник программы на таких языках мало уступает программе на "специальном языке". При этом сохраняется присущая 3-му поколению "близость к аппаратуре", что тоже, как выяснилось на примере самых-самых оптимизирующих современных компиляторов, очень даже востребовано для успеха мероприятия.
Но должны были пройти те самые 30 лет, чтобы сформировалось понимание, как будет лучше — т.е. удобней для человека и эффективней для машины.
А так-то на момент разработки SQL классикой 3-го поколения были C/Pascal/Lisp, классикой 4-го поколения Prolog/REXX/sh.
Ну понятно, что от плохого понимания перспектив развития IT язык SQL получился чем-то вроде Пролога, ы-ы-ы. Собсно, внутренняя механика обеих языков имеет много общего. В этом месте стоит включить честность и заметить, что при наличии альтернатив Прологу от него легко отказываются.
S>А если нагрузка в полмиллиона транзакций в секунду не планируется — то можно обойтись и значительно более скромной аппаратурой, и выжимать такты на "статика против динамики" не потребуется.
Выжимать такты требуется всегда.
Такова наша реальность примерно с 2004-го года, когда кривая развития процов вошла в хорошо различимое насыщение.
А последние 4-5 лет так и вовсе на месте замерло.
Усё, приплызд.
Теперь надо повернуться лицом к софту и научить его выжимать максимум из железок.
V>>Аналог. В некоторых языках пошли на хитрость, сумев при почти таком же синтаксисе превратить SQL-запросы в полноценные выражения ФП-подобного языка. Но далее уже идёт строгая типизация и прочие плюшки развитого языка. S>Это мы мне рассказываем про Linq?
Нет, это было до Linq.
Я же говорил много раз — Linq интересен, жаль что опоздал лет на 10.
И это множит его на ноль.
Вся инстраструктура донета развивалась без Linq.
А если бы его выкатили сразу, то C# не рассматривался бы как "еще одна джава" или как "Паскаль с сишным синтаксисом". Этот язык тогда бы рассматривали как "другой язык". Вон Пролог — это же "другой" язык, верно? )) Не как безликие-однотипные С/Паскаль/Джава.
V>>Современные оптимизаторы отслеживают не только типы, они отслеживают жизненный цикл данных, принимают решения по трансформации графа операций с данными и т.д. S>А статистику они откуда берут?
Статистику берут оттуда же.
S>Откуда они знают, что при одном значении параметра надо сканировать один индекс, а при другом — другой?
А откуда это известно в динамике? ))
В динамике нужно пройтись по всем таблицам, посмотреть у кого какие индексы, построить варианты.
Примерно так работает тот самый Пролог.
Но наличие индексов у таблиц — это статическая информация, её не нужно обрабатывать в динамике.
Далее. У подавляющего большинства запросов совсем маленькое количество вариантов планов, которые останутся после анализа статической информации. Собсно, я уже повторяюсь — я предлагал генерить как наборы самих планов, так и оптимизированный код их оценки.
Сейчас оценка происходит крайне медленно, поэтому иногда принимается решение взять "достаточно хороший" план, а не лучший.
Ну и, не знаю, стоит ли расписывать всевозможные ситуации.
Допустим, есть два варианта плана по запросу из 3-х таблиц. По одному плану идёт скан таблиц 1, 2, 3, по другому — 1, 3, 2. Нетрудно заметить, что уже в статике становится понятно, что одновременно с оценкой каждого плана уже можно сканировать таблицу 1.
Далее. Само сканирование (маппинг полей — проекции, вычисляемые поля и выражения при join т.д.) — сегодня это сильно тормозная штука в общих затратах (ведь это классика интерпретирования), бо скорость чтения с современных SSD-массивов приблизилась к скорости чтения обычной RAM. Это раньше можно было спекулировать на "этих затрат не видно и под микроскопом в сравнении со стоимостью чтения с диска", а сегодня забудь об этом аргументе навсегда. ))
V>>Там же сразу появляются мощные библиотеки, т.е. всё по-взрослому. V>>А писанных тобой лично процедур — резко сократилось бы. V>>Так у меня в любой базе жил еще заметный утилитно-библиотечный слой. S>Ну да, примерно так и есть. Хотя чётко отделить кто пишет какой слой скорее всего не получится.
Фантазировать прямо отсюда — это как разрабатывать SQL в 70-х годах. ))
Тут надо просто дать инструмент и посмотреть куда кривая выведет.
Заметь, что бурное в последние годы развитие самих языков (C++/Java/C#) диктуется исключительно прикладным кодом на этих языках.
Т.е. вот она обратная связь.
V>>У меня сие "осознание" произошло еще до 97-го года. S>А выглядит так, что оно появляется ровно в процессе этого разговора.
Брехня. Мы с тобой по этой теме цеплялись еще в 2004/2005-хх, но ты был совсем невменяем. ))
Собсно, на тот момент альтернатив не было ваапще никаких и попытки критиковать текущее положение вещей смотрелись дико, согласен.
Я и огребал.
Но так-то с 97-98-го года своё мнение не поменял — принципы работы с реляциоными СУБД весьма убоги.
Собсно, достаточно написать парочку больших приложений на БД чтобы увидеть, что даже 3-я нормальная форма — это миф, в живой природе не встречается, не говоря уже о форме Бойса-Кодда. Про 4-ю и выше вообще забудьте — ничего сложнее записной книжки в нормальные формы не воткнёшь.
S>Причём очень медленно, потому что кое-то всеми силами избегает конкретных утверждений. Вместо "в языке Scala есть вот такая штука"
Просто мне сложно отвечать конкетно на абстрактные вопросы.
Там чел стал спрашивать конкретней — я иотвечал конкретней.
И да — это моя фишка, критиковать тебя за эдакую "скользкость", за постоянный контроль путей отступления.
Всегда поражался этим чудесам стеснительности.
S>пишется "есть некоторые языки, которые менее ограничены кое-в-чём, по сравнению с кое-какими другими языками". Понятно, что на вот таких полунамёках построить полноценную дискуссию затруднительно.
Дисскуссию сложно строить на "ату его, ату!"
Но абсолютно каждый оппонент начинает именно с этого. ))
Это слава богу, что уже есть и неплохие компиллируемые NoSQL и прочие альтернативы, которые показывают какие-то совершенно дикие результаты в сравнении с "обычными" СУБД. Мне сейчас психологически банально легче, бо когда совсем уж против ветра было — то удовольствие не из изысканных.
V>>В общем, тут декомпозицией не отделаешься, тут дизайн языка с 0-ля менять надо. S>Вот тут всегда возникает дилемма: слишком далёкий от привычного язык даст нулевую заинтересованность. Слишком близкий — даёт мало толку. Языки изобретать тяжело (по крайней мере, хорошие).
С этим не поспоришь.
Я поэтому и не берусь изобретать язык. ))
Это дело вкуса и вдохновения.
Но я могу подкидывать требования к такому языку.
Это уже инженерия.
S>Опять же — как делать: по языку для каждого слоя, или один на всех?
Один с достаточной выразительностью.
S>Основной язык слишком императивный.
РА декларативна по-сути.
Т.е., хотя задана эдакая императивность операций, но это как в ФП-языках — императивность там только на бумаге, а на деле компилятор может выбирать последовательность вычислений и вообще проводить нетривиальные преобразования.
Ну и, говорил уже, нужна и РА и РИ.
Собсно, в современном Linq именно так и есть.
Просто РА сугубо императивна и практически не оптимизируется.
S>В современном мейнстриме мы имеем либо вавилон из JS+Java+SQL, когда каждую фичу должно делать три разработчика плюс два тестера плюс отдельный менеджер, чтобы следить, чтобы все края совпали, либо JS everywhere с феерически неэффектиывым бэкендом и базой данных.
Про JS я даже говорить не хочу, если честно.
В сравнении с JS обсуждаемый SQL — просто верх человеческой мысли. ))
V>>Просто лично я за такой язык, который допускал бы и статическую компиляцию с максимумом проверок/ограничений/оптимизаций. V>>Но, если потянуть за эту ниточку — там вытягивается слишком много кардинальный отличий от нынешних мейнстримовых практик. S>Чтобы штука заработала, надо, чтобы она окучивала целую вертикаль — вот прямо от клиента и до сервера.
От сервера до готовой к линковке транспортной либы для клиента. Причём, типа как из CORBA — бинд на кучу языков.
Блин, да я готов довольно много поставить на то, что в конце всех концов "оно" именно так и будет.
Там и выхода-то другого нет.
Стандарты — штука капризная.
Protobuf появился вопреки всем стандартам и стал бешенно популярным, помножив весь IDL на ноль и почти на ноль XML-сообщения.
Это тупая инженерная хрень.
Тупейшая.
Бо отвечает прямо на прямо поставленные инженерные вопросы.
Но так и должно.
S>Я об таком в свободное время фоном думаю, но во-первых, уделяю мало времени, во-вторых, не уверен, что это всё ещё актуально.
Дело не в актуальности. Дело в некоей привычки воспринимать реальность как данную свыше.
В итоге, мы ежедневно закрываем глаза на кучу откровенных глупостей, делаем вид, что так и надо.
Но любой вдруг ставший популярным фреймворк или язык не возникал на ровном месте — сначала возникала идея. ))
S>Грубо говоря, непонятно, нужны ли ещё людям те приложения, которые я себе воображаю.
Нужны.
S>TPC-C вышел из моды потому, что уже лет 15 никто не пишет учётные системы.
Пишут конструкторы учётных систем. ))
А еще никто не разворачивает выч. мощности "сам", их теперь арендуют и почти всегда есть доступ к "достаточной" мощности.
Но так-то всё в силе, в любом случае.
S>Нет хороших фреймворков и вообще понимания, что и как должно делаться. Глобально — потому, что люди, выделяющие финансирование, катастрофически некомпетентны. Им показывают прототипы из одной странички, за которыми стоит база из 5 строчек. Когда начинается нормальная нагрузка — то либо проект дохнет (если не успевает принести денег), либо под него нанимаются мега спецы, которые способны собрать кастом билд MySQL и прикрутить статическую оптимизацию к PHP. Людям такого уровня "библиотеки" и "фреймворки" вообще не нужны — они сами могут компилятор сварганить.
Сварганить компилятор не сложно, можно за несколько вечеров на коленке.
А вот оптимизатор — это на той самой грани прогресса современного IT.
S>А начинающие выбирают инструменты, которые позволяют "через полчаса в продакшн", а не те, которые позволяют за день написать код, который после пилота смасштабируется в 10000 раз по объёму и нагрузке.
Да. Должны быть сами такие "автомастшабируемые" ср-ва.
А они (по опыту в других областях) получаются только при использовании высокоуровневых параметрических моделей.
Т.е. вот встречается в программе описание некоего хранилища, а к нему хинт — ожидается сотня записей. А к другой таблице другой хинт — ожидается сотня миллионов записей. И одни и те же (внешне) операции начинают выполняться резко по-разному. А параметрическая модель — она живет в самом компиляторе и (по-хорошему) неплохо бы уметь эти модели ему скармливать извне тоже (это всё еще к вопросу требований к языку и инфраструктуре вокруг него).
Ну и, один из самых популярных способов оптимизации в С++ сегодня — это оптимизация по показаниям профайлера.
Т.е. собрали, запустили профайлер. А затем пересобрали уже с показаниями профайлера.
Для БД это вообще идеальный сценарий, тогда и хинты ручками указыать не надо, они будут расставляться профайлером по-факту.
V>>Почему rsdn тормозит? )) S>RSDN для своего объёма и железа просто летает. При этом у него внутри как раз MS SQL + linq2db.
ЧТД, "своего железа".
А не дикого кластера.
Отсюда и пляшем.
Здравствуйте, vdimas, Вы писали:
V>Здравствуйте, Sinclair, Вы писали:
T>>>Может и тупик, но проблема эта — не проблема ORM. Это проблема языков, которые требуют на любой чих делать отдельный класс. S>>Нет. Это проблема — именно ORM. Потому что без ORM мы на тех же языках работаем с рекордсетами, которые не требуют порождать по классу на запрос. И прекрасно биндим их хоть в UI, хоть в бизнес-логику.
V>Это ограничения языков, где "класс" — это что-то занимающее место в релизе. V>В компиллируемых языках типы стираются.
Дело не в бинарнике, а в объёме рукопашного кода. Если мне надо каждый select предварять отдельной декларацией public class StudentFirstAndLastName, то я умру это делать, и откажусь от проекций совсем. В классических ORM-приложениях так и делают — там принято не задумываться о том, что мы протаскиваем через игольное ушко лишние мегабайты.
В Linq ситуация чуть-чуть получше, с возможностью локально использовать анонимные классы. Но этого всё равно недостаточно для того, чтобы писать по-настоящему универсальный повторно используемый код.
Потому что я не могу написать, к примеру, функцию, которая принимает на вход "IQueryable, параметризованный любым типом с FirstName и LastName", и возвращающую "IQueryable, параметризованный типом с теми же свойствами, что и у аргумента, плюс string FullName".
Хотя уже можно делать штуки типа
IQueryable<T> FilterByDateRange(this IQueryable<T> input, Expression<Func<T, DateTimeOffsetDate>> dateSelector DateTimeOffset? from, DateTimeOffset? to)
{
var query = input;
if(from.HasValue)
query = from q in query where dateSelector(q) >= @from.Value select q;
if(to.HasValue)
query = from q in query where dateSelector(q) >= to.Value select q;
return q;
}
И не велосипедить однообразные ветки if в "прикладных" функциях:
Здравствуйте, vdimas, Вы писали:
V>Мы говорим о ситуации в современом IT.
Ой, это такая размытая штука, эта ваша "ситуация в современном IT".
V>Это не современное IT.
V>Я это не предполагал. V>Я предлагал посмотреть на ходовые сценарии и что в них не так.
В них много чего не так. Например, хреновая отказоустойчивость некластерных решений.
S>>На ноуте и SQLite будет показывать отличные результаты. V>Не будет.
Будет. У нас, есличо, один проект внезапно вырос со 100 "строк" до 300K "строк" (а это, для нашего продукта, уже объёмы, которые создают телекомы мирового уровня, с десятками миллионов долларов месячного оборота в рамках этого конкретного продукта), оставаясь на SQLite. В котором, к слову, почти все таблицы были устроены как (int id, varchar(max) jsonData).
От этой реализации отошли по причинам, не связанным с производительностью
V>Зависит от сценариев. V>Когда надо в основном только отдавать данные, то MySQL на современной технике практически вне конкуренции.
Когда надо "только отдавать", да ещё и при select * from mytable where id = ?, справится вообще кто угодно.
S>>А пока что речь идёт о том, как бы он круто выиграл забег, если бы ему дали. V>Дык, он и выиграл давным давно. V>Чуть менее чем весь современный веб опирается на MySql в бэкенде.
Это передёргивание. Чуть менее чем весь современный веб опирается на Apache и PHP. Что не мешает быть говном и тому и другому.
V>На нескольких обычных, обслуживающих непересекающиеся рынки. V>Потому что важен не только и не столько throughput, сколько latency. V>А приличные цифры latency сегодня дают ни в коем случае не кластеры, а хорошо вылизанные "единичные" серваки.
Ух ты! И что, одно failure материнской платы положит NASDAQ на время замены этой "обычной машинки"?
V>На этом кластере при его чудовищной througput показана одна из самых плохих latency — порядка 0.1 сек. V>Это только в мусорку по современным реалиям.
Приложений, где нужна латентность лучше, чем 100мс, единицы. Биржевая торговля — да, согласен, тут надо прямо мигом.
А где ещё? Обработка кредиток? Там и 1000мс всех устроит, и 3000мс.
V>Выжимать такты требуется всегда.
Да ну? Почему ж тогда у нас сайты все сплошь работают на тормозных PHP и Apache, а не на, скажем, хотя бы Java и lighttpd? И уж тем более не на nginx и C++?
На чём-то приемлемом написаны доли процента всего веба.
V>Теперь надо повернуться лицом к софту и научить его выжимать максимум из железок.
Хотелось бы надеяться. Но пока что типичный шаг по "оптимизации производительности" соверменного проекта — это перевод его докер-контейнера в dedicated server. Вот мы в 50 раз и ускорились.
V>Нет, это было до Linq.
Интересно посмотреть, о чём это идёт речь.
V>>>Современные оптимизаторы отслеживают не только типы, они отслеживают жизненный цикл данных, принимают решения по трансформации графа операций с данными и т.д. S>>А статистику они откуда берут?
V>Статистику берут оттуда же.
Непонятно, что такое "оттуда же". В жизни не видел оптимизатора, который бы учитывал хотя бы среднюю длину строки, которую будут передавать в функцию strstr.
V>А откуда это известно в динамике? )) V>В динамике нужно пройтись по всем таблицам, посмотреть у кого какие индексы, построить варианты.
А также посмотреть на гистограммы, и на разнообразные constraints.
Именно это делают реальные RDBMS. Пользуясь, собсно, тем, что у них есть описание запроса в виде AST, с логическими операциями в узлах.
При этом мы можем скомпилировать код сегодня, а работать он будет через год — с актуальными на тот момент данными.
И когда мы добавляем к таблице индекс, нам не нужно останавливать систему на несколько часов, чтобы компилятор перекомпилировал бинарник, на ходу перестраивая сотни тысяч планов.
V>Но наличие индексов у таблиц — это статическая информация, её не нужно обрабатывать в динамике.
V>Далее. У подавляющего большинства запросов совсем маленькое количество вариантов планов, которые останутся после анализа статической информации. Собсно, я уже повторяюсь — я предлагал генерить как наборы самих планов, так и оптимизированный код их оценки. V>Сейчас оценка происходит крайне медленно, поэтому иногда принимается решение взять "достаточно хороший" план, а не лучший.
Практически всегда принимается именно такое решение. V>Допустим, есть два варианта плана по запросу из 3-х таблиц. По одному плану идёт скан таблиц 1, 2, 3, по другому — 1, 3, 2. Нетрудно заметить, что уже в статике становится понятно, что одновременно с оценкой каждого плана уже можно сканировать таблицу 1.
У джойна трёх таблиц 6 вариантов порядка соединения. Умножить на два-три варианта алгоритма соединения (лишние отбрасываем). Умножить на количество потенциальных индексов, которые можно использовать.
Ну, то есть получаем два-три десятка вариантов. Как будет выглядеть "оптимизированный код их оценки"?
V>Далее. Само сканирование (маппинг полей — проекции, вычисляемые поля и выражения при join т.д.) — сегодня это сильно тормозная штука в общих затратах (ведь это классика интерпретирования), бо скорость чтения с современных SSD-массивов приблизилась к скорости чтения обычной RAM. Это раньше можно было спекулировать на "этих затрат не видно и под микроскопом в сравнении со стоимостью чтения с диска", а сегодня забудь об этом аргументе навсегда. ))
Чушь. Лучшие SSD всё ещё в десяток раз дороже памяти в терминах латентности и в сотню раз — в терминах bandwidth.
Нет, я не настаиваю на интерпретации, но выбор подходящего алгоритма, который минимизирует обращения к диску, всё ещё важнее оптимизации сканирования уже загруженной страницы.
V>Это слава богу, что уже есть и неплохие компиллируемые NoSQL и прочие альтернативы, которые показывают какие-то совершенно дикие результаты в сравнении с "обычными" СУБД. Мне сейчас психологически банально легче, бо когда совсем уж против ветра было — то удовольствие не из изысканных.
Это кто у нас неплохие NoSQL?
Я всё жду, когда придёт кто-то компилируемый, и обскачет лидеров TPC-C. Причём не обязательно пердолиться абсолютным tpmC c мегакластерами — покажите, как ваша уберплатформа уделывает MS SQL Express на обычном серваке на ксеоне.
На практике внезапно оказывается, что все эти хвалёные NoSQL применимы только для каких-то других задач, не тех, для которых проектировали RDBMS. V>Но я могу подкидывать требования к такому языку. V>Это уже инженерия.
Ну, так-то да. Мне вообще непонятно даже, с чего начинать — декларативно всё должно быть, или императивно?
То есть — есть ли у нас assignment или только definition?
S>>Опять же — как делать: по языку для каждого слоя, или один на всех?
V>Один с достаточной выразительностью.
S>>Основной язык слишком императивный.
V>РА декларативна по-сути. V>Т.е., хотя задана эдакая императивность операций, но это как в ФП-языках — императивность там только на бумаге, а на деле компилятор может выбирать последовательность вычислений и вообще проводить нетривиальные преобразования.
V>Ну и, говорил уже, нужна и РА и РИ. V>Собсно, в современном Linq именно так и есть. V>Просто РА сугубо императивна и практически не оптимизируется.
S>>В современном мейнстриме мы имеем либо вавилон из JS+Java+SQL, когда каждую фичу должно делать три разработчика плюс два тестера плюс отдельный менеджер, чтобы следить, чтобы все края совпали, либо JS everywhere с феерически неэффектиывым бэкендом и базой данных.
V>Про JS я даже говорить не хочу, если честно. V>В сравнении с JS обсуждаемый SQL — просто верх человеческой мысли. ))
V>>>Просто лично я за такой язык, который допускал бы и статическую компиляцию с максимумом проверок/ограничений/оптимизаций. V>>>Но, если потянуть за эту ниточку — там вытягивается слишком много кардинальный отличий от нынешних мейнстримовых практик. S>>Чтобы штука заработала, надо, чтобы она окучивала целую вертикаль — вот прямо от клиента и до сервера.
V>От сервера до готовой к линковке транспортной либы для клиента. Причём, типа как из CORBA — бинд на кучу языков.
V>Блин, да я готов довольно много поставить на то, что в конце всех концов "оно" именно так и будет. V>Там и выхода-то другого нет.
S>>Иначе — будь любезен, соответствуй общепринятым стандартам.
V>Стандарты — штука капризная. V>Protobuf появился вопреки всем стандартам и стал бешенно популярным, помножив весь IDL на ноль и почти на ноль XML-сообщения. V>Это тупая инженерная хрень. V>Тупейшая. V>Бо отвечает прямо на прямо поставленные инженерные вопросы. V>Но так и должно.
S>>Я об таком в свободное время фоном думаю, но во-первых, уделяю мало времени, во-вторых, не уверен, что это всё ещё актуально.
V>Дело не в актуальности. Дело в некоей привычки воспринимать реальность как данную свыше. V>В итоге, мы ежедневно закрываем глаза на кучу откровенных глупостей, делаем вид, что так и надо. V>Но любой вдруг ставший популярным фреймворк или язык не возникал на ровном месте — сначала возникала идея. ))
S>>Грубо говоря, непонятно, нужны ли ещё людям те приложения, которые я себе воображаю.
V>Нужны.
S>>TPC-C вышел из моды потому, что уже лет 15 никто не пишет учётные системы.
V>Пишут конструкторы учётных систем. )) V>А еще никто не разворачивает выч. мощности "сам", их теперь арендуют и почти всегда есть доступ к "достаточной" мощности. V>Но так-то всё в силе, в любом случае.
S>>Нет хороших фреймворков и вообще понимания, что и как должно делаться. Глобально — потому, что люди, выделяющие финансирование, катастрофически некомпетентны. Им показывают прототипы из одной странички, за которыми стоит база из 5 строчек. Когда начинается нормальная нагрузка — то либо проект дохнет (если не успевает принести денег), либо под него нанимаются мега спецы, которые способны собрать кастом билд MySQL и прикрутить статическую оптимизацию к PHP. Людям такого уровня "библиотеки" и "фреймворки" вообще не нужны — они сами могут компилятор сварганить.
V>Сварганить компилятор не сложно, можно за несколько вечеров на коленке. V>А вот оптимизатор — это на той самой грани прогресса современного IT.
S>>А начинающие выбирают инструменты, которые позволяют "через полчаса в продакшн", а не те, которые позволяют за день написать код, который после пилота смасштабируется в 10000 раз по объёму и нагрузке.
V>Да. Должны быть сами такие "автомастшабируемые" ср-ва. V>А они (по опыту в других областях) получаются только при использовании высокоуровневых параметрических моделей.
V>Т.е. вот встречается в программе описание некоего хранилища, а к нему хинт — ожидается сотня записей. А к другой таблице другой хинт — ожидается сотня миллионов записей. И одни и те же (внешне) операции начинают выполняться резко по-разному. А параметрическая модель — она живет в самом компиляторе и (по-хорошему) неплохо бы уметь эти модели ему скармливать извне тоже (это всё еще к вопросу требований к языку и инфраструктуре вокруг него).
V>Ну и, один из самых популярных способов оптимизации в С++ сегодня — это оптимизация по показаниям профайлера. V>Т.е. собрали, запустили профайлер. А затем пересобрали уже с показаниями профайлера. V>Для БД это вообще идеальный сценарий, тогда и хинты ручками указыать не надо, они будут расставляться профайлером по-факту.
Да, я давно уже думаю о том, что все современные методики изоляции транзакций построены на концепции "интерактивной сессии". Когда сел Вася за консоль, написал "set transaction isolation level serializable; go; begin tran; go; select top 100 * from customer_orders order by createDate desc go", Enter. Потянулся, закурил, и сидит. Думает. А Оракл тем временем сегмент отката щёлк!щёлк!. Ну, или MS SQL там за сценой shared range lock держит, и все операторы при сохранении заказов видят "Please wait...".
Потому что хрен его знает, что там этот Вася дальше планирует, накурившись-то?
А ведь в реале мы можем точно знать, что там будет происходить. Клиент (ну, или миддл-тир) обязан всю транзакцию, как она есть, отправить серверу на исполнение. Нельзя на ходу "придумать" следующий стейтмент — все ходы заранее записаны.
Тогда и уровни изоляции будут не нужны — оптимизатор и так видит, будут ли там повторные чтения, или нет; или что вот у нас в строке 1 прочитались данные, в строке 5 использовались, и больше они нам не нужны — поэтому все shared lock на них можно уже отпускать, не дожидаясь конца транзакции.
По идее, вот такие штуки могут ещё на порядок поднять быстродействие OLTP в том же железе, при сохранении ACID гарантий.
V>ЧТД, "своего железа". V>А не дикого кластера. V>Отсюда и пляшем.
Ну, так это же community-проект, с нулевым бюджетом и нулевой прибылью. А в коммерческом софте так не бывает — он приносит прибыль, и можно планировать затраты.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[25]: В России опять напишут новый объектно-ориентированны
Здравствуйте, Sinclair, Вы писали:
S>>>На ноуте и SQLite будет показывать отличные результаты. V>>Не будет. S>Будет. У нас, есличо, один проект внезапно вырос со 100 "строк" до 300K "строк" (а это, для нашего продукта, уже объёмы, которые создают телекомы мирового уровня, с десятками миллионов долларов месячного оборота в рамках этого конкретного продукта), оставаясь на SQLite.
подтверждаю про sqlite и не только на ноуте. у нас на продакшене SQLite с базой под 10Г и миллионами записей, всё норм.
sqlite не подходит только когда частота транзакций на запись большая, тк в этом случае транзакции идут последовательно.
а запросы на чтение одновременно в параллель выполняются норм, даже запись не мешает чтению.
а с учетом что sqlite inproc, скорости на порядок лучше чем у серверных БД.
Re[16]: В России опять напишут новый объектно-ориентированны
Здравствуйте, Sinclair, Вы писали:
S>Дело не в бинарнике, а в объёме рукопашного кода. Если мне надо каждый select предварять отдельной декларацией public class StudentFirstAndLastName, то я умру это делать, и откажусь от проекций совсем. В классических ORM-приложениях так и делают — там принято не задумываться о том, что мы протаскиваем через игольное ушко лишние мегабайты.
Уже же сто раз обсуждалось тут и демонстрировалось на работающих примерах. Что достаточно наличия в языке самых базовых основ метапрограммирования, как данная задача полностью автоматизируется и становится незаметной для пользователя (в данном случае программиста, использующего соответствующую библиотеку для работы с SQL).
Re[16]: В России опять напишут новый объектно-ориентированны
Здравствуйте, Sinclair, Вы писали:
V>>Это ограничения языков, где "класс" — это что-то занимающее место в релизе. V>>В компиллируемых языках типы стираются. S>Дело не в бинарнике, а в объёме рукопашного кода. Если мне надо каждый select предварять отдельной декларацией public class StudentFirstAndLastName, то я умру это делать, и откажусь от проекций совсем. В классических ORM-приложениях так и делают — там принято не задумываться о том, что мы протаскиваем через игольное ушко лишние мегабайты.
Абсолютно согласен.
Поэтому я и позволил себе говорить о другом языке, заточенном на все эти сценарии с данными.
Проекция — это ж наипервейшая операция порождения типов кортежей "по-месту".
Т.е. можно повторять бесконечно — РА и РИ строго типизированы в своей сути.
S>В Linq ситуация чуть-чуть получше, с возможностью локально использовать анонимные классы.
Тоже верно. Но мне, как разработчику, хочется сделать этот автовыводимый тип как public. Более того, я еще хочу иметь возможность присвоить этому типу имя.
(Тут ты уже начинаешь быть конструктивным — проводишь анализ и выходишь на некие пункты из большого списка требований)
И я не хочу слишком странного, заметь. ))
Например, в современном С++ такое возможно через комбинацию auto, typedef и decltype.
Но даже такая связка недостаточно удобна, как по мне, т.к. декларация typedef — она независимая от целевого метода, возвращающего "анонимный" тип, а хочется именно привязать одно к другому.
S>Но этого всё равно недостаточно для того, чтобы писать по-настоящему универсальный повторно используемый код.
Да. "Мелочей" хватает, стоит только копнуть. О чём и речь.
Примеры можно приводить бесконечно.
Например, взять автовычисляемые поля.
Если "исходники" данных для вычисляемого поля так же идут по сети в рамках того же экземпляра кортежа, то значения автовычисленных полей, передаваемых по сетке, будут избыточными. В общем, когда некая "одна система" будет ответственна за оба конца транспорта, то она может использовать знания о происходящем для оптимизаций ф-ии доставки данных.
S>Потому что я не могу написать, к примеру, функцию, которая принимает на вход "IQueryable, параметризованный любым типом с FirstName и LastName", и возвращающую "IQueryable, параметризованный типом с теми же свойствами, что и у аргумента, плюс string FullName".
На шаблонах С++ можно. В любом случае в момент компиляции всё разресолвится.
И как раз под это дело разрабатывают концепты.
Концепты можно наложить сверху, чтобы исключить, скажем, банальные описки.
Вдруг ты опишешься в исходнике шаблона и у тебя наряду с FullName будет обращение к полю FullNam, и ни дай бог в подаваемом типе кортежа будет поле FullNam — в этом случае даже компилятор не поможет. Такие сценарии были замечены в плюсах давно, поэтому и вышли на необходимость концептов, которые активно разрабатываются для одной из следующих версий языка.
Т.е., предполагаемый сценарий примерно такой: для целей активной разработки удобней использовать параметрический полиморфизм с минимумом ограничений (зависимостей), а ближе к устаканиванию можно пройтись по коду и расставить более строгие "концепты", исключая потенциальную интерференцию описок и имён идентификаторов. Пусть компилятор работает, верно?
Для нынешней динамики SQL это всё недостижимо, ес-но. О проблемах узнаешь только в рантайм и то, зачастую когда уже поздно. ))
S>Хотя уже можно делать штуки типа S>IQueryable<T> FilterByDateRange(this IQueryable<T> input, Expression<Func<T, DateTimeOffsetDate>> dateSelector DateTimeOffset? from, DateTimeOffset? to)
Но выглядит страшно, согласись. ))
S>И не велосипедить однообразные ветки if в "прикладных" функциях:
C# вообще плохой пример — его параметрический полиморфизм неполноценен.
Ограничения типов (которые на сейчас сейчас даются в виде интерфейсов и базовых классов) должны составлять полную сигнатуру типов и их членов, но эти ограничения не входят в сигнатуру типа и его мемберов.
В С++ тоже не входят, но трюк с частичной специализацией позволяет разруливать аналогичные сценарии хотя бы для типов. Но для методов напрямую разрулить невозможно, тоже косяк. Поэтому применяют следующую технику:
метод<T1, T2, ..>(T1 arg1, T2 arg2, ...) { вспомогательный_тип_диспетчер<T1, T2, ..>::целевой_код(arg1, arg2, ...); }.
И это я не в кач-ве ликбеза даю а лишь с целью демонстрации того, что определённые знания по проблематике существующих языков есть, т.е. есть довольно внушительный список пожеланий к языкам, что именно от них надо, чтобы не извращаться в коде как показывал ты или я.
Здравствуйте, Sinclair, Вы писали:
V>>Мы говорим о ситуации в современом IT. S>Ой, это такая размытая штука, эта ваша "ситуация в современном IT".
Железо, на котором крутится rsdn — вполне себе "современная ситуация".
Причём, мейнстримовая (плюс-минус не так далеко).
V>>Я это не предполагал. V>>Я предлагал посмотреть на ходовые сценарии и что в них не так. S>В них много чего не так. Например, хреновая отказоустойчивость некластерных решений.
Гы. Кластера бывают разные.
Там как раз прямое отображение на соотв. уровни raid — т.е. как дублирование данных, так и распараллеливание нагрузки.
Плюс еще комбинации того и другого.
Обсуждаемые цифры поверх Sun-кластера случились не от дублирования, а от распараллеливания, но ты сейчас напираешь на дублирование.
Считай, что был пойман на спекуляции.
S>>>На ноуте и SQLite будет показывать отличные результаты. V>>Не будет. S>Будет.
В сравнении с MySQL — нет.
S>У нас, есличо, один проект внезапно вырос со 100 "строк" до 300K "строк" (а это, для нашего продукта, уже объёмы, которые создают телекомы мирового уровня, с десятками миллионов долларов месячного оборота в рамках этого конкретного продукта), оставаясь на SQLite. В котором, к слову, почти все таблицы были устроены как (int id, varchar(max) jsonData). S>От этой реализации отошли по причинам, не связанным с производительностью
Ну, SQLite может показывать чуть лучшие результаты только за счёт того, что это встраиваемая база.
MySQL тоже идёт не только как сервер, но и позволяет быть подлинкованным в виде библиотек.
Еще неплохой результат показывал MS SQL CE, если нарисовать ему ручками свой шедуллер/pipeline, вместо штатных ср-в и без всяких .Net.
Но! Проекты MySQL и SQLite интересны тем, что показывают — СУБД можно разрабатывать даже "на коленке".
Первые их версии были убоги по меркам современных Oracle/MS SQL/DB2, но были мощнее, скажем, версии Oracle 5.
Потому что большая ретроспектива. Потому что, хоть это самые что ни на есть наколенные поделки (в отличие от PostgreSQL, который насквозь академический), но даже наколенность-то была выполнена с учётом хорошего (уже) понимания реалий работы с данными.
Отсюда успех.
А уже сегодня MySQL поспорит с версий (не побоюсь этого слова) Oracle 7. При этом все "кишки" наружу, все либы есть. Можно использовать классически SQL (фронтенд) через отдельный сервис, либо в виде встраиваемой СУБД, но так же во втором случае можно непосредствено оперировать таблицами, т.е. "дергать" за бэкенд напрямую.
Понимаешь, к чему я клоню? ))
V>>Зависит от сценариев. V>>Когда надо в основном только отдавать данные, то MySQL на современной технике практически вне конкуренции. S>Когда надо "только отдавать", да ещё и при select * from mytable where id = ?, справится вообще кто угодно.
Уже при двух join начинается разница.
Но так-то да, MySQL так же показывает определённую философию и образ мышления, а именно — сценарии работы с даными бывают РАЗНЫМИ.
Т.е., серебрянной пули нет. Под разные сценарии хороши разные алгоритмы и разные стратегии хранения информации. MySQL изначально затачивался именно на быструю выборку данных и в этой дисциплине рвёт всех. Поэтому, практически весь современный веб на нем и крутится.
S>>>А пока что речь идёт о том, как бы он круто выиграл забег, если бы ему дали. V>>Дык, он и выиграл давным давно. V>>Чуть менее чем весь современный веб опирается на MySql в бэкенде. S>Это передёргивание. Чуть менее чем весь современный веб опирается на Apache и PHP. Что не мешает быть говном и тому и другому.
ngix, скорее.
И да, PHP для своего времени был прекрасен.
Ведь это именно в рамках PHP индустрией был отлажен подход к шаблонизации HTML-страниц, который практически без изменения пошел в JSP и ASP, с точностью до меток начала/конца кода шаблона.
К тому же, движков PHP существует несколько, в том числе компиллируемых, которые рвут как тузик грелку JSP и ASP.Net.
В том числе этому способствует гладкая стыковка с нейтивными модулями, писанными, скажем, на С/С++.
К тому этому способствует специфика управления памятью — во многих "акселераторах" память убирается только после выполнения запроса или серии их, что идеально ложится на специфику веба. Дотнетный же GC, увы, может начать работу в самый неподходящий момент. ))
Помимо шаблонизатора, как сам скриптовый язык PHP тоже весьма неплох, особенно с 5-й версии.
По крайней мере рядом с его тогдашним самым популярным современником — Перлом.
Похоже, ты не понимаешь, за что ругают PHP.
Его ругают за децентрализованность.
За то, что его слабо связанные с друг другом библиотеки и фреймворки, сваленные в кучу, превратились в натуральную помойку.
За то, что он задал тот самый "низкий порог вхождения" одним из первых в отрасли, со всеми полагающимися светошумовыми эффектами.
Это был совершенно новый для индустрии опыт. ))
Т.е. PHP помойка не из-за св-в языка (он весьма неплох, повторюсь), а потому что такая сложилась вокруг него культура.
Что-то типа как вокруг современного JS — тоже та еще складывается помоечка.
Здравствуйте, Sinclair, Вы писали:
S>Потому что я не могу написать, к примеру, функцию, которая принимает на вход "IQueryable, параметризованный любым типом с FirstName и LastName", и возвращающую "IQueryable, параметризованный типом с теми же свойствами, что и у аргумента, плюс string FullName".
В принципе, возможны как минимум два варианта. Первый — реализация интерфейса IFirstLastNameble и возврат типа с параметризированным типом и новым свойством. Второй — не очень сложное постукивание в бубен Expression Tree.
Если нам не помогут, то мы тоже никого не пощадим.
Re[26]: В России опять напишут новый объектно-ориентированны
Здравствуйте, vdimas, Вы писали:
V>Железо, на котором крутится rsdn — вполне себе "современная ситуация". V>Причём, мейнстримовая (плюс-минус не так далеко).
Эммм, WhatsApp, ngs.ru, и какой-нибудь likefish.ru тоже являются современной ситуацией.
Причём первых — единицы, вторых — сотни, а третьих — легион.
Рассматривать железо без нагрузки — бессмысленно. А нагрузка у нас в диапазоне от 10^2 до 10^7 пользователей в сутки.
V>Гы. Кластера бывают разные.
С т.з. RDBMS — примерно одинаковые. V>Обсуждаемые цифры поверх Sun-кластера случились не от дублирования, а от распараллеливания, но ты сейчас напираешь на дублирование. V>Считай, что был пойман на спекуляции.
Дублирование без распараллеливания и не получится.
V>В сравнении с MySQL — нет.
Спорно.
V>Ну, SQLite может показывать чуть лучшие результаты только за счёт того, что это встраиваемая база.
А также за счёт того, что он принудительно single-user. Что позволяет очень сильно упростить шедулинг транзакций. V>Еще неплохой результат показывал MS SQL CE, если нарисовать ему ручками свой шедуллер/pipeline, вместо штатных ср-в и без всяких .Net.
Очень может быть. Речь идёт о том, что в таких вырожденных сценариях любые "compact", "express", "light", и "local" версии летают на ура.
Взрослая RDBMS обязана уметь вылезать за пределы коробки, и поддерживать несколько более широкий класс сценариев.
V>Понимаешь, к чему я клоню? ))
Нет пока.
V>Уже при двух join начинается разница.
Ну, в принципе — да. Но надо понимать, что современный ноут — это 16GB памяти, что позволяет достигать 100% cache hit ratio для большинства read-only приложений. Поэтому разница в планах запросов внезапно начинает играть значительно меньшую роль, чем для сценария классической RDBMS, когда данные таки надо доставать с диска.
V>Но так-то да, MySQL так же показывает определённую философию и образ мышления, а именно — сценарии работы с даными бывают РАЗНЫМИ.
MySQL показывает философию "функциональность важнее производительности". MS SQL проектировался как классический корпоративный продукт со стратегическими целями. То есть, к примеру, фича про "исполнение .net кода" — это сразу приоритет 0, и пофиг на стоимость, а фича "хранить json в таблице" идёт где-то в конце списка с пометкой "а это ещё нахрена?".
V>Т.е., серебрянной пули нет. Под разные сценарии хороши разные алгоритмы и разные стратегии хранения информации. MySQL изначально затачивался именно на быструю выборку данных и в этой дисциплине рвёт всех. Поэтому, практически весь современный веб на нем и крутится.
Нет. MySQL затачивался под то, чтобы быть удобным для использования. Затачивание на быструю выборку означало бы развитый оптимизатор — а по факту его допиливали задним числом. Оно означало бы забивание на фичи по модификации — а по факту мы имеем и replace statement, и безтранзакционный движок, и ещё много чего.
Современный веб крутится на нём ровно потому, что MySQL в течение многих лет был единственной бесплатной опцией.
V>ngix, скорее.
Неа. Nginx, конечно же, используется. https://trends.builtwith.com/web-server
Почти так же часто, как Apache. Но надо же понимать, что эти 28% — это фронт-енд, т.е. позади этих nginx по-прежнему стоят apache. V>Ведь это именно в рамках PHP индустрией был отлажен подход к шаблонизации HTML-страниц, который практически без изменения пошел в JSP и ASP, с точностью до меток начала/конца кода шаблона.
Вообще-то, PHP, JSP, и ASP — это три (ну, ладно, два) разных подхода к шаблонизации HTML-страниц.
При этом синтаксически JSP и ASP гораздо ближе друг к другу, чем к PHP.
Но давайте не будем углубляться в детали этой истории.
V>К тому же, движков PHP существует несколько, в том числе компиллируемых, которые рвут как тузик грелку JSP и ASP.Net.
Отож. Всегда можно найти сценарий, на котором выиграет выбранный движок.
V>В том числе этому способствует гладкая стыковка с нейтивными модулями, писанными, скажем, на С/С++. V>К тому этому способствует специфика управления памятью — во многих "акселераторах" память убирается только после выполнения запроса или серии их, что идеально ложится на специфику веба. Дотнетный же GC, увы, может начать работу в самый неподходящий момент. ))
Серверный — нет.
V>Похоже, ты не понимаешь, за что ругают PHP.
Во-первых, неважно, за что его ругают. Речь идёт о том, что PHP — это очевидно хреновый выбор для написания веб-приложений.
Какой критерий ни возьми — всегда найдётся кто-то лучше. Особенно это очевидно, если посмотреть в перспективе — нам же надо сравнивать не современный PHP с современным JSP, а, скажем, PHP образца 2000 года с JSP образца 2000 года.
Там вообще всё очевидно — и тем не менее, "народ" проголосовал за PHP.
V>Его ругают за децентрализованность.
В основном его ругают за противоречивость. Семьдесят семь способов сделать любую фигню, и сотни директив конфигурации, которые меняют смысл твоего кода на противоположный.
Именно из-за этого страницы, которые работали годами, внезапно начинают сыпаться, как шифер с крыши под ураганом.
Повторюсь: неважно, какие конкретно претензии к PHP. Важно, что по статистике использования качество продукта оценивать нельзя. Поэтому я предлагаю а) прекратить обсуждение истории и достоинств PHP (а заодно и Apache) и б) прекратить приводить статистические аргументы.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[17]: В России опять напишут новый объектно-ориентированны
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, Sinclair, Вы писали:
S>>Потому что я не могу написать, к примеру, функцию, которая принимает на вход "IQueryable, параметризованный любым типом с FirstName и LastName", и возвращающую "IQueryable, параметризованный типом с теми же свойствами, что и у аргумента, плюс string FullName".
IT>В принципе, возможны как минимум два варианта. Первый — реализация интерфейса IFirstLastNameble и возврат типа с параметризированным типом и новым свойством. Второй — не очень сложное постукивание в бубен Expression Tree.
Эмм, походу, я отстал от жизни.
В C++ я бы мог использовать для результата наследника параметра.
Что-то типа
template<typename T> class FullNameType: public T
{
public std::string getFullName(); // { return base.getFirstName() + " " + base.getLastName();}
}
public IQueryable<FullNameType<T>> AddFullName(IQueryable<T> source);
Тогда бы у меня результат содержал бы как .getFirstName(), так и .getFullName().
Но ведь в CLR запрещено наследоваться от параметра шаблона. Как тут быть? Делать
class FullNameType<T>
where T:IFirstLastName
{
public T Wrapped { get; }
public string FullName { get; }
}
И писать v.Wrapped.FirstName?
Это как-то криво — этак дважды обернёшь, и начнётся Wrapped.Wrapped.FirstName.
C ExpressionTree тоже непонятно — я понимаю, что можно покрутить "внутри" реализации IQueryable. Но не понимаю, как будет выглядет сигнатура функции.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[17]: В России опять напишут новый объектно-ориентированны
Здравствуйте, vdimas, Вы писали:
V>Тоже верно. Но мне, как разработчику, хочется сделать этот автовыводимый тип как public. Более того, я еще хочу иметь возможность присвоить этому типу имя.
Вот тут мне не вполне понятно — зачем имя этому типу?
Вот смотри, как я себе это представляю. Допустим, мы хотим отдать клиенту какой-то view (пока что пренебрежём всем этим ajax-ом).
Ну там — юзернейм, ласт логин, форумлист, топиклист, и т.п.
Для того, чтобы удобно было делать разметку, мы хотим иметь типизированное свойство Model.
Пишем (в биндинге, в коде, или ещё где) this.Model.User.LoginNam; — и нам сразу среда автодополняет, а компилятор статически ругается, если мы не дописали свойство правильно.
В классике нам для этого нужно продекларировать свойство Model заранее:
public class MainView: View
{
MainViewModel Model {get; set;}
}
Без имени типа — никак.
Ок, как устроен этот тип? Да там — точно так же: свойства этого класса имеют "проекционные" типы, которые мы, в идеале, описываем исключительно с помощью выражений.
То есть лучше всего было бы прямо вот так:
public class MainView: View
{
var Model {get; } = new {
ForumList = (from f in DB.Forums where f.Parent.IsNull() select f.ShortName, f.Description, f.Id),
TopicList = (from t in DB.Topics where t.ForumID == this.CurrentForum orderby t.LastReplyDate descending select t.Subject, t.ReplyCount, t.LastReplyDate, t.Author.NickName, t.Id),
User = (from u in users where u.Id == this.CurrentUserId).SingleOrDefault()
};
}
Тут нам имя типа для этого Model вообще ненужно. Он используется ровно один раз.
Ну, ок, этот код выглядит не слишком опрятно. Опрятнее было бы как-то так:
public class MainView: View
{
var Model {get; } = BuildModel();
}
Да и внутри BuildModel хотелось бы побольше структурированности — чтобы все вот эти вот кишочки стейтментов наружу не торчали. Там же на самом деле будет развесистая-развесистая хрень: и LastReplyDate, и ReplyCount не хранятся, а вычисляются; везде применяются атрибуты безопасности — типа удалённые сообщения нужно прятать от всех, кроме модераторов, ну и прочее, и прочее.
Почти всё, что нам нужно, работает (то есть работало бы) через конструктор анонимного класса:
var model = new {
ForumList = getForums(),
TopicList = getTopics(CurrentForumId),
User = getUserDetail(CurrentUserId)
};
Здесь подразумевается выведение типов:
var getForums = () => from f in DB.Forums where f.Parent.IsNull() select f.ShortName, f.Description, f.Id;
var getTopics = (int forumId) => from t in DB.Topics where t.ForumID == forumId orderby t.LastReplyDate descending select t.Subject, t.ReplyCount, t.LastReplyDate, t.Author.NickName, t.Id;
В современном C# этому мешает, по большому счёту, одна проблема — отсутствие автовывода возвращаемого типа.
В именованных типах ещё и типы свойств надо декларировать явно, но это можно почти что обойти при помощи декларации анонимных типов.
А вот с автовыводом возврата всё совсем плохо. Для полноценных методов этого вообще нет. Можно было бы заменить на лямбды, как я выше показал, но увы — сериал Lost поучаствовал и здесь: CS0815 "Cannot assign lambda expression to an implicitly-typed variable"
Понятно, что мы-то здесь подразумеваем не Func<>, а Expression<Func>, потому что всю эту кунсткамеру нам предстоит компилировать в SQL (ну или во что-то ещё, для передачи в RDBMS execution pipeline). Но компилятору этого не объяснишь.
Впрочем, такое уж различие между Expression<> и Func<> — это опять какая-то искусственная ерунда.
С учётом того, что внутри лежит байткод, я не вижу никакой причины не встраивать оба типа конверсии — прямой и обратный — в эти выражения.
И вообще, более правильно спроектирован, скажем, Regex — там нет дуализма между скомпилированными и интерпретируемыми выражениями, а вместо этого есть только флаг в конструкторе.
Который, по моему мнению, тоже избыточен. Не вижу никакой причины заставлять программиста предсказывать частоту использования конкретного регекспа (ну, или нашего лямбда-выражения).
Этим должен заниматься рантайм — аналог JIT-а. Мы же всегда можем рассчитать как стоимость компиляции регекспа, так и стоимость его выполнения в обоих вариантах. Увидели, что нам передали гигабайтную строку -ок, компилируем.
Увидели, что интерпретируем тот же регексп в сотый раз — компилируем.
И то же самое с Expression. Понадобилось нам проехаться по AST — ок, берём у Method свойство Statements и поехали.
Понадобилось его реально вычислить — берём и вычисляем.
А что там делается за кадром — это дело среды.
V>Например, в современном С++ такое возможно через комбинацию auto, typedef и decltype. V>Но даже такая связка недостаточно удобна, как по мне, т.к. декларация typedef — она независимая от целевого метода, возвращающего "анонимный" тип, а хочется именно привязать одно к другому.
Ну вот надо начинать со схемы использования. Как Хейльсберг начал проектировать Дельфи со строчки на доске: Label1.Font.Color := clGray;
V>Например, взять автовычисляемые поля. V>Если "исходники" данных для вычисляемого поля так же идут по сети в рамках того же экземпляра кортежа, то значения автовычисленных полей, передаваемых по сетке, будут избыточными. В общем, когда некая "одна система" будет ответственна за оба конца транспорта, то она может использовать знания о происходящем для оптимизаций ф-ии доставки данных.
V>На шаблонах С++ можно. В любом случае в момент компиляции всё разресолвится.
Это понятно. Но нам надо не только стереть типы при компиляции, но и как-то оставить достаточно данных для движка RDBMS, чтобы обеспечить runtime-execution.
Сейчас оптимизаторы традиционных ЯП и оптимизаторы RDBMS устроены очень-очень сильно по разным принципам.
Разработка оптимизатора, который сочетает в себе оба подхода, тянет на десяток PhD thesis. V>Для нынешней динамики SQL это всё недостижимо, ес-но. О проблемах узнаешь только в рантайм и то, зачастую когда уже поздно. ))
Ну, в рамках разработки подхода динамикой SQL можно пренебречь. То есть мы можем считать, что у нас есть волшебный объект DB, с мемберами, которые адекватно описывают всю-всю схему данных в базе. Его модификация — это тяжёлая штука, т.к. она требует перелопачивания фактически хранимых данных. Как это описать — отдельный вопрос.
И мы поверх DB строим объекты типа Model, которые описывают "вычисляемую" часть модели (их может быть много — столько, сколько нужно для работы). Они сами по себе stateless. Это даже скорее не объекты, а выражения — то есть нам нужны функции getMainPageViewModel(DB, viewParam1, viewParam2, ...), которые описывают, как получить данные для отображения.
С модификациями там будет ещё отдельный сложный вопрос.
S>>Хотя уже можно делать штуки типа S>>IQueryable<T> FilterByDateRange(this IQueryable<T> input, Expression<Func<T, DateTimeOffsetDate>> dateSelector DateTimeOffset? from, DateTimeOffset? to)
V>Но выглядит страшно, согласись. ))
Да не так то и страшно. Лишнего страху нагоняет Expression, без которого в нормальной среде можно было бы и обойтись.
V>Ограничения типов (которые на сейчас сейчас даются в виде интерфейсов и базовых классов) должны составлять полную сигнатуру типов и их членов, но эти ограничения не входят в сигнатуру типа и его мемберов.
Да тут дело не в ограничениях. Вот в этом же упрощённом примере я мог бы пойти по одному из трёх путей:
1. Потребовать у типа элемента коллекции иметь свойство Date (СPP-style)
2. Потребовать у типа элемента коллекции наследоваться от IDatedObject { DateTimeOffset Date { get; }} (CLR-style)
3. Потребовать у пользователя метода передавать селектор для даты
Как видим из примера использования, первые два способа неприемлемы, т.к. у объекта может быть более одного свойства типа даты, а ведут они себя в данном случае одинаково.
Это не так очевидно для синтетического примера с First и Last name, но и в нём нужно поступать примерно так же.
Потенциальным улучшением было бы умение использовать "дефолтные" значения селекторов для самых частых случаев. То есть если мы не передали ничего в dateSelector, то подразумевается o=>o.DocumentDate. (потенциально решаемо на С++ частичной специализацией).
Но в любом случае ограничения нам тут нужны во вторую очередь.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[32]: В России опять напишут новый объектно-ориентированны
Здравствуйте, vdimas, Вы писали:
V>Кароч, дословно тебе была расписана следующая схема: V>- есть запросы с параметрами или без (некие "уникальные"); V>- по каждому запросу с параметром или "уникальному" хранится НАБОР планов; V>- говорилось о возможности компактного представления в памяти наборов всех (не выкинутых заведомо) планов всех запросов.
V>Набо-о-ор. Набор! Это такое множество. Их несколько, обычно, планов на запрос-то. V>Много таких планов на каждый такой запрос. V>Все хранятся. V>Потому что не умеют порождаться в рантайм. V>Раз, раз, приём, приём, вы еще с нами? V>Их все надо породить в compile time и каким-то хитрым образом сохранить.
V>А раз их все надо хранить, неужели это не означало, что они могут понадобиться? V>Ну Семён Семёныч! V>Ну разумеется, конкретный план для запроса будет выбран из НАБОРА их в зависимости от: V>- значений параметров; V>- текущих значений статистики; V>- текущего уровня дефрагментации индексов.
V>То бишь, какая там в опу "другая константа"? V>Даже подавая одну и ту же константу в один и тот же запрос в разные времена жизни базы можно наблюдать выбор разных планов для исполнения.
Ухты. После ста страниц диагнозов профессионализма внезапно переходим к конкретике. Действительно, было бы лучше, если бы перед этой дискуссией кое-кто почитал учебники типа Гарсиа-Молина. Ну, чтобы понимать, как устроен "план запроса", чем физический план отличается от логического, и почему нет такого понятия, как "дерево планов запросов".
Компактное представление в памяти — это, конечно, интересно. Но для того, чтобы его конструктивно обсуждать, придётся понять, что именно хранится внутри этого таинственного "плана запроса".
А там, внезапно, в каждом узле хранится много "локальной" информации. Например, для пары таблиц, участвующих в Join, там будут храниться конкретные индексы, предикаты, и residuals для этого join. И их там как бы дофига, потому что потенциально orders o join manager m on o.managerId = m.id порождает бездну вариантов исполнения. Грубо говоря, мы можем использовать любой из 5-6 индексов по Manager, потому что а вдруг там в where что-то особенно селективное написано, и любой из 10-15 индексов по order. Итого получаем от полусотни до сотни вариантов исполнения этого join. А для вложенных подзапросов там вообще ад и израиль.
Но основная дупа для идеи "компактного представления" ещё и в том, что "внутри" каждого из этих вариантов плана вшиты детали "окружающего" запроса, то есть, если, к примеру, у меня там где-то затесался where ManagerName like @managerNamePrefix+'%', то у меня в аргументах джойна так и будет стоять не index, а результат index scan c соответствующим предикатом.
Это означает, что этот вот кусочек плана запроса я не смогу использовать в плане, построенном для другого запроса.
Шансов на то, что удастся что-то "склеить", т.е. сослаться на один и тот же узел плана запросов несколько раз из разных деревьев, очень мало. И чем больше размер поддерева, тем больше в нём специфики, и тем меньше шансов на повторное использование. Общая экономия будет близка к нулю. Так что можно косвенно оценить расходы места под статическую таблицу планов, почитав различные гайды для DBM. Там, где опытные камрады говорят "ну, в принципе 2GB под кэш планов — это немного". Причём в кэш попадают исключительно только те планы, которые были реально использованы движком — то есть из наших 50-100 кандидатов на простой join, в кэш попадёт 1. Если у нас есть большое разнообразие статистики (например,в одной стране менеджеров больше, чем заказов, а в другой — наоборот), то через какое-то время в кэш может попасть ещё пара вариантов.
Чтобы хранить прямо все-все-все варианты, нам потребуются сотни гигабайт. А для тех запросов, где вариантов немного, их и хранить особо незачем — проще построить их на ходу.
И вот всё это как бы очевидно людям, которые реально занимались оптимизацией реальных SQL запросов как full-time job, а не только единожды сдали 32х часовой курс реляционной алгебры 20 лет назад.
Поэтому и не получается конструктивной дискуссии — уж очень разный у вас с Иваном уровень подготовки. Тебе кажется, что он чего-то непонимает ровно потому, что он весь ход твоей мысли уже в голове воспроизвёл, получил результаты, прикинул их к реальности, и видит заблуждения, допущенные на самом начальном этапе.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[18]: В России опять напишут новый объектно-ориентированны
Здравствуйте, Sinclair, Вы писали:
S>Эмм, походу, я отстал от жизни. S>В C++ я бы мог использовать для результата наследника параметра.
Если нам нужно повторно используемое расширение в виде свойства FullName для всех сущностей, у которых есть поля FirstName, LastName, то на linq2db это делается просто и без затей.
1. Создаём интерфейс
interface IFullNameble // имя по вкусу
{
string FullName { get; set; }
}
2. В T4 шаблоне создания модели добавляем интерфейс куда надо
Здравствуйте, Sinclair, Вы писали: V>>Тоже верно. Но мне, как разработчику, хочется сделать этот автовыводимый тип как public. Более того, я еще хочу иметь возможность присвоить этому типу имя. S>Вот тут мне не вполне понятно — зачем имя этому типу? S>Вот смотри, как я себе это представляю.
желаемая структура
S>Допустим, мы хотим отдать клиенту какой-то view (пока что пренебрежём всем этим ajax-ом). S>Ну там — юзернейм, ласт логин, форумлист, топиклист, и т.п. S>Для того, чтобы удобно было делать разметку, мы хотим иметь типизированное свойство Model. S>Пишем (в биндинге, в коде, или ещё где) this.Model.User.LoginNam; — и нам сразу среда автодополняет, а компилятор статически ругается, если мы не дописали свойство правильно. S>В классике нам для этого нужно продекларировать свойство Model заранее: S>
S>public class MainView: View
S>{
S> MainViewModel Model {get; set;}
S>}
S>
S>Без имени типа — никак. S>Ок, как устроен этот тип? Да там — точно так же: свойства этого класса имеют "проекционные" типы, которые мы, в идеале, описываем исключительно с помощью выражений. S>То есть лучше всего было бы прямо вот так:
S>
S>public class MainView: View
S>{
S> var Model {get; } = new {
S> ForumList = (from f in DB.Forums where f.Parent.IsNull() select f.ShortName, f.Description, f.Id),
S> TopicList = (from t in DB.Topics where t.ForumID == this.CurrentForum orderby t.LastReplyDate descending select t.Subject, t.ReplyCount, t.LastReplyDate, t.Author.NickName, t.Id),
S> User = (from u in users where u.Id == this.CurrentUserId).SingleOrDefault()
S> };
S>}
S>
S>Тут нам имя типа для этого Model вообще ненужно. Он используется ровно один раз. S>Ну, ок, этот код выглядит не слишком опрятно. Опрятнее было бы как-то так:
S>
S>public class MainView: View
S>{
S> var Model {get; } = BuildModel();
S>}
S>
S>Да и внутри BuildModel хотелось бы побольше структурированности — чтобы все вот эти вот кишочки стейтментов наружу не торчали. Там же на самом деле будет развесистая-развесистая хрень: и LastReplyDate, и ReplyCount не хранятся, а вычисляются; везде применяются атрибуты безопасности — типа удалённые сообщения нужно прятать от всех, кроме модераторов, ну и прочее, и прочее.
Описанное тобой реализуется вот прямо сейчас на C++ в одну строчку.
Хотя при этом я не вижу ничего ужасного и в использование именованного типа.
Но главное, я не очень понимаю, какое это вообще имеет отношение к обсуждаемой теме отказа от SQL. )
Re[19]: В России опять напишут новый объектно-ориентированны
Здравствуйте, alex_public, Вы писали: _>Описанное тобой реализуется вот прямо сейчас на C++ в одну строчку.
А можно на неё посмотреть? _>Хотя при этом я не вижу ничего ужасного и в использование именованного типа.
Объём кода удваивается (в лучшем случае). Именованный тип — это же не только имя, но и вся структура.
Это я сначала должен описать класс User, потом — класс проекции списка форумов, класс проекции списка сообщений, потом уже класс модели, который собирает свойства всех этих трёх классов.
Эдак и вспотеть можно. _>Но главное, я не очень понимаю, какое это вообще имеет отношение к обсуждаемой теме отказа от SQL. )
Самое прямое. Вот это — код BuildModel() — и есть то, что должно быть вместо SQL.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[20]: В России опять напишут новый объектно-ориентированны
Здравствуйте, Sinclair, Вы писали:
_>>Описанное тобой реализуется вот прямо сейчас на C++ в одну строчку. S>А можно на неё посмотреть?
Как-то так:
auto BuildModel()
{
return db(select(t.a, t.b).from(t).where(t.a>10));
}
class MainView: View
{
decltype(BuildModel()) Model=BuildModel(); //та самая одна строчкаvoid Test() {for(auto& row: Model) cout<<row.a<<row.b<<endl;}
};
_>>Хотя при этом я не вижу ничего ужасного и в использование именованного типа. S>Объём кода удваивается (в лучшем случае). Именованный тип — это же не только имя, но и вся структура. S>Это я сначала должен описать класс User, потом — класс проекции списка форумов, класс проекции списка сообщений, потом уже класс модели, который собирает свойства всех этих трёх классов. S>Эдак и вспотеть можно.
Не, я имею в виду только имя для типа модели в данном примере. Понятно, что проекции и т.п. должны автоматически отрабатывать.
_>>Но главное, я не очень понимаю, какое это вообще имеет отношение к обсуждаемой теме отказа от SQL. ) S>Самое прямое. Вот это — код BuildModel() — и есть то, что должно быть вместо SQL.
Хм, а мне казалось, что в BuildModel находится код, который должен генерировать то нечто, что заменит SQL. Или ты предлагаешь отсылать в СУБД напрямую код на универсальном языке высокого уровня? )
Re[21]: В России опять напишут новый объектно-ориентированны
Ну круто. Так и надо.
_>Не, я имею в виду только имя для типа модели в данном примере. Понятно, что проекции и т.п. должны автоматически отрабатывать.
В данном примере типы именам не нужны.
_>Хм, а мне казалось, что в BuildModel находится код, который должен генерировать то нечто, что заменит SQL. Или ты предлагаешь отсылать в СУБД напрямую код на универсальном языке высокого уровня? )
С точки зрения разработчика, существует только BuildModel. Как оно и во что транслируется инфраструктурой — это интересно только при профилировании. Точно так же, как средний программист на C# не очень интересуется, какой там будет MSIL, что сделает JIT, и как там интел переведёт эти абстрактные mov eax, [ebx] в RISC-инструкции внутреннего языка.
Язык, которым мы описываем BuildModel, должен быть в меру универсальным.
То есть, к примеру, он не должен прямо сосать-сосать на арифметике, как это делает SQL. Однако ему вредно быть настолько близким к железу, как C++ — скажем, голые поинтеры, да и вообще поинтеры, ему противопоказаны.
При этом я считаю, что на этом же языке должно быть можно написать функцию, скажем, расчёта MD5, и она должна в итоге работать не сильно хуже её С++ — аналога.
Потому что ситуация, в которой внутри SQL есть фиксированный набор "магических" функций, а для его расширения надо писать на каком-то отдельном языке — ужасна.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.