Здравствуйте, gandjustas, Вы писали:
G>>>Тогда специально для тебя еще раз объясняю. Задача СУБД — оптимизировать чтение с диска. EP>>1. Одна из задач, далеко не единственная. Причём это низкоуровевая постановка задачи, а высокоуровневая звучит как — оптимизировать скорость доступа к данным. G>Данные лежат на диске если что.
Релевантные данные могут полностью находится в памяти.
EP>>2. Я изначально рассмотрел два аспекта
: в первом существенно то что кэш занимает меньше памяти чем заняли бы эквивалентные страницы (и возможно не поместились бы, либо были вымыты из памяти и т.п.), а во втором сравнивается скорость в том случае когда и кэш и эквивалентные страницы полностью помещаются в пмять. Так вот, здесь мы находимся как раз во втором варианте — зачем ты вообще сюда пытаешься приплести чтение с диска? G>Потому что когда база умещается целиком в память, о вообще нет смысла считать.
"Эквивалентные" страницы для запроса могут помещаться в память, даже в случае когда вся база нет.
G>Время раундтрипа до базы окажется выше разницы между отдачей результата из кеша и из страниц в памяти. Даже при высоком hit ratio.
1. На обработку данных может понадобится десятки миллисекунд. Например для dummy пробежки одним ядром по ста магабайтам требуется около десяти миллисекунд. Roundtrip может быть намного меньше.
2. Даже если roundtrip намного больше, то всё равно есть преимущество — процессор/память базы не нагружается, соответственно больше свободных ресурсов для обработки других задач. То есть даже при большом latency всё равно для хорошего throughput много применений
G>>>Чтение одной "страницы" занимает 5-10 мсек, EP>>Это HDD, причём в случае случайного доступа — если же грузится пачка последовательных страниц, то намного меньше G>А у тебя есть уверенность, что тебе нужна последовательная пачка?
Конечно же нет — но это не повод выдавать частные утверждения за общие.
G>Станицы в файле данных обычно выделяются случайным образом, так как выделяется только первая свободная.
А разве СУБД не старается положить страницы таблицы рядом? Например те же extent'ы.
EP>>Для БД также используют SSD. G>И что?
А то что для SSD чтение рандомной страницы будет как минимум в разы быстрее.
G>>>сколько там операций в памяти можно сделать за это время?
EP>>При последовательном доступе в одно ядро можно выдуть около десяти гигабайт за одну секунду, причём особо не напрягаясь. EP>>За десять миллисекунд — около ста мегабайт. Если же результат обработки сотни мегабайт уже готов, то очевидно различия будут не доли миллисекунд как ты опрометчиво заявлял ранее. G>Это ты о чем сейчас?
G>Тытоже не понимаешь как базы работают? Когда данные уж в ОП, то там различия минимальные, доли миллисекунд.
Даже для обработки сотен мегабайт, что совсем немного по меркам современных объёмов RAM — требуется десятки миллисекунд (одним ядром), а никакие не "доли"
EP>>А что тут "не доказано"? То что закэшированный запрос по данным в памяти может отличаться не на доли миллисекунд от обычного обхода (утверждение №1)? Вроде очевидно G>Также очевидно, что память скушанная кешем приведет к повышению количества чтений с диска. Но тебе почему-то неочевидно.
Это очевидно, но только для некоторых случаев. Я привел конкретные контрпримеры где количество чтений будет меньше — и ты даже согласился, как минимум в случае агрегирования.
Речь о том, что не нужно делать чрезмерно общие заявления, справедливые только для некоторых частных случаев.
G>Также очевидно что при равной вероятности любых запросов hit ratio будет нулевым и кеш по факту не будет работать, а при неравномерном распределении та же проблема решается индексами. Но тебе это тоже неочевидно.
Конечно это не очевидно, так как контрпример строится элементарно.
G>Причем этим очевидным вещам ты противопоставляешь чисто теориетические выкладки. Приведи хоть один результат тестов, который подтверждает твои слова.
Опять таки, хотя бы на счёт агрегации ты согласился, так? Тогда зачем тест?
Или ты всё же считаешь что это практически не осуществимо? Если так, то что мешает?
EP>>То есть без практических примеров ты не можешь понять утверждение №1? G>Понять != поверить.
Поясни. Что конкретно тебе понятно, и во что ты "не веришь" для утверждения №1?
EP>То что закэшированный запрос по данным в памяти может отличаться не на доли миллисекунд от обычного обхода (утверждение №1)?
G>>>Можно лишь констатировать факт, что я немного больше знаю и имею больше опыта про субд и кеширование EP>>Я об этом сразу сказал, можешь констатировать это хоть в каждом сообщении — аргументации это не добавит. G>Это я к тому, что твоя агрументация слаба.
Аргументы либо верные, либо нет — разница в опыте тут совершенно ортогональна. Их может быть недостаточно для основания утверждения, но в этом случае достаточно привести контраргумент.
Либо сами аргументы могут быть не верные, но и в этом случае достаточно привести контраргумент.
Апелляция к опыту может прокатить только против каких-то субъективных суждений. Пример субъективного суждения: "ИМХО, LINQ сильно тормозит".
Если же приводится объективное высказывание — "кэш результатов может уменьшить количество чтений с диска" — то тут апелляция к опыту не катит, как минимум она никак не опровергает это утверждение.
G>>>поэтому твои теоретические выкладки не могу принять. EP>>Да не принимай — я привёл технические "выкладки". Если ты видишь в них ошибку, то тебе достаточно привести технический контраргумент, а не разглагольствовать на тему — можешь ли ты это принять или нет G>Я тебе привел уже несколько раз и в этом посте тоже. Ты их банально игнорируешь.
Ты приводишь не контраргументы, а лишь говоришь что для каких-то частных случаев это не справедливо — с чем я кстати согласен. Но, тем не менее, это никак не опровергает технические "выкладки".
G>>>>>Не продолжай пожалуйста. EP>>>>Давай, удачи, слив засчитан G>>>Тебе, конечно, никто не мешает считать себя умнее, но умнее от этого ты не станешь. Увы. EP>>Вот уже и лирика пошла, слабо оставаться в техническом русле? G>То есть G>
G>слив засчитан
G>ты считаешь "техническим руслом" ?
Нет, это ответ на твоё хамство.
G>Тогда я из него никогда и не выходил.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Если они создаются в одном месте — то да, в условиях Compacting GC это будет самый вероятный вариант.
Про то что потоков может быть несколько забываем, да?
EP>Но, чем на более низком уровне мы делаем реализацию — тем естественно больше появляется дополнительных ньюансов типа перемещения памяти/fixed.
Ну да, и своим fixed ты получишь прямо противоположный эффект — тормоза.
Здравствуйте, gandjustas, Вы писали:
EP>>Здесь под динамическими фильтрами и предикатами — подразумеваются выражения неизвестные во время сборки приложения. Их "специальность" в том, что для них нельзя построить индексы заранее, а не в том что у них какой-то особенный синтаксис. G>Ты предполагаешь, что любой запрос равновероятен?
Необязательно.
G>Тогда чем поможет кеш?
Закэширует равновероятные запросы (которые помечены например как "result cache").
G>А если не равновероятен, то в чем проблема построить индексы?
1. Например акцент распределения меняется со временем — индекс сегодня подходящий для 95%, завтра может подходить лишь для 5% запросов.
2. Другой пример: ок, выделили 80% типичных запросов, построили для них индексы — но под остальные запросы они никак не подходят, и паттерны доступа там меняются со временем. Так вот, кэши могут ускорить оставшиеся 20%, чтобы они повторно не грузили систему.
3. Набор покрывающих индексов может оказаться слишком дорог. Причём даже если не брать в рассмотрение место на дисках, то они отнимают RAM, что увеличивает чтения с диска — так как для разных "индексированных" запросов требуются разные индексы, и помимо этого требуется сама таблица для менее частых (но всё же актуальных) "не индексированных" запросов.
S>>>Индексированное представление — один из хороших вариантов сделать "прикладное кэширование", показав базе, какие производные данные мы ожидаем часто видеть в запросах. EP>>Как создать индекс для динамических формул? G>Нету в SQL динамических формул, они все для СУБД одинаковые.
С точки зрения зрения приложения они динамические, так как не известны на этапе компиляции.
Здравствуйте, Ночной Смотрящий, Вы писали:
EP>>Если они создаются в одном месте — то да, в условиях Compacting GC это будет самый вероятный вариант. НС>Про то что потоков может быть несколько забываем, да?
Здравствуйте, Evgeny.Panasyuk, Вы писали:
G>>А если не равновероятен, то в чем проблема построить индексы?
EP>1. Например акцент распределения меняется со временем — индекс сегодня подходящий для 95%, завтра может подходить лишь для 5% запросов. EP>индекс сегодня подходящий для 95%, завтра может подходить лишь для 5% запросов.
Где вы такое видели? "Мы вам заказали систему под одно, но по ходу выяснили, что нам нужно совершенно другое". Так это будет новая система.
Приведите, пожалуйста, пример из жизни с подобной сменой требований.
Здравствуйте, Слава, Вы писали:
EP>>индекс сегодня подходящий для 95%, завтра может подходить лишь для 5% запросов. С>Где вы такое видели? "Мы вам заказали систему под одно, но по ходу выяснили, что нам нужно совершенно другое". Так это будет новая система. Приведите, пожалуйста, пример из жизни с подобной сменой требований.
Нет, дело не в смене требований. Изначально требуется возможность применять динамические формулы/предикаты — например выражение вводится пользователем/аналитиком. Каждый день могут быть популярны какие-то определённые но разные варианты.
Здравствуйте, Ночной Смотрящий, Вы писали:
НС>Только создатели, похоже, об этом не знают. Если брать стандарт, то он вообще то совсем не типизирован.
Ну, я бы тактично назвал его либерально-выразительным. Авторы дизайнили его так, чтобы при работе с реальными данными не приходилось обкладывать запросы тоннами бойлерплейт-преобразований. Отсюда либеральные type coercion rules.
НС>Конкретные реализации обычно типизированны динамически (и то не все, sqlite, к примеру, позволяет себе менять типы внутри одного рекордсета). При этом, что особенно смешно, если немного изменить буквально пару конструкций (наложить дополнительные ограничения), то из SQL можно сделать статически типизированный язык, все типы кортежей которого выводятся без обращения к данным, зная только метаданные таблиц.
Не всё так просто. Как только мы начнём завинчивать гайки, начнутся всякие неприятности. Ну там окажется, что банальный запрос "выведи мне агентов, продавших выше среднемесячного" начинает падать с требованием руками объяснить, урезать ли bigmoney до money или расширять money до bigmoney.
НС>Не только. Как минимум есть еще и IQueryable, который позволяет делать на две головы более гибкое API минимальными усилиями.
Это и есть "запросы". Т.е. я могу принять IQueryable<MyInterestingData>, обработать его, и вернуть IQueryable<SomethingElse>.
При этом входной IQueryable может ссылаться на что угодно — на таблицу, view, результат применения любой адской магии — мне всё равно.
Ничего подобного нет ни в одном известном мне диалекте SQL, не говоря уже о стандарте.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>И что должен показать этот конкретный пример?
То, что практических случаев, когда кэш результатов внутри СУБД будет полезен, можно пересчитать по пальцам. Задней ноги. Лошади.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здесь под динамическими фильтрами и предикатами — подразумеваются выражения неизвестные во время сборки приложения. Их "специальность" в том, что для них нельзя построить индексы заранее, а не в том что у них какой-то особенный синтаксис.
На всякий случай поясню, что построение индексов заранее, во время сборки приложения — это малоинтересный частный случай.
Нам интереснее возможности по тюнингу производительности в процессе эксплуатации. Мы, фанаты РСУБД, считаем, что необходимость пересборки приложения для улучшения производительности — признак несостоятельности разработчика.
В том-то и состоит вся мощь РСУБД, что я могу мониторить поведение приложения, и на основе реально наблюдаемых явлений спустя месяцы и годы тюнить индексы так, как автору приложения и в голову не приходило.
И краеугольный камень этого — генерация приложением реальных запросов, а не вытаскивание в него случайных данных для "дальнейшей обработки".
EP>Как создать индекс для динамических формул?
Смотря для каких. EP>Не будет никакой высокой производительности для выражений задающихся извне.
Смотря для каких. Как ни странно, для большинства прикладных случаев, даже выражения, задающиеся извне, вовсе не ставят себе задачу проверить полноту SQL по Тьюрингу. Обычно всё достаточно банально — скажем, формула расчёта премии сравнивает показатели с нормативами.
Набор показателей варьируется, нормативы варьируются, но для каждого из интересных нам выражений не так уж трудно построить покрывающий индекс.
Расчёт премий делается ежемесячно; нормативы обычно пересматриваются ежеквартально; а набор показателей — не чаще, чем раз в несколько лет.
Вполне достаточно времени для того, чтобы отпрофилировать актуальный набор запросов по расчёту премий и разогнать его до нужной скорострельности.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Ну, я бы тактично назвал его либерально-выразительным. Авторы дизайнили его так, чтобы при работе с реальными данными не приходилось обкладывать запросы тоннами бойлерплейт-преобразований.
Не нужны в реальных запросах никакие преобразования. Если что, я в свое время реализовал строго типизированный аналог SQL. И, разумеется, там, в отлмичие от реального SQL, был оператор приведения типов. Так вот, в реальных запросах он применялся крайне редко (в основном если в запросе был UNION).
Динамика там появилась по совсем другой причине. Дело в том что у создателей была идея фикс — запросы должны были писать бухгалтера, а не программисты. Поэтому они всячески старались приблизить SQL к естественному языку и убрать все программистско-специфичные моменты. Идея давно и с грохотом провалилась, но артефакты ее язык несет и по сю пору.
S>Не всё так просто.
Все именно так просто. Я проверял. Строго-типизированный вариант прекрасно работает. Нерешенных неприятностей на момент, когда я покинул проект не было.
S>Ну там окажется, что банальный запрос "выведи мне агентов, продавших выше среднемесячного" начинает падать с требованием руками объяснить, урезать ли bigmoney до money или расширять money до bigmoney.
Это все сравнительно легко решаемо. В конце концов cast никто не отменял. Ну и на практике подобное встречается совсем нечасто.
Здравствуйте, gandjustas, Вы писали:
G>В деньгах? Огромный. Например в одном банке (не могу назвать в каком по причине NDA) своя разработка кушает не более 5% ИТ бюджета, а услуги внешних компаний — около 20%. Причем в баках реально большие расходы на ИТ, в остальных отраслях соотношение еще меньше.
Так мы же не про деньги говорили, а про количество программистов. )))
_>>В C# может и нет, а в других языках есть. Что тебе тут и продемонстрировали. Просто ты этого упорно не хочешь признавать. G>Это ты веришь что они есть. А я не увидел ничего близкого по функционалу по сравнению с тем, что было в моих приложениях.
Ну ну) Пока что единственное, что тебе не продемонстрировали (причём это не означает, что с этим есть какие-то проблемы), это переброску запроса между dll. Но кстати говоря это ты и сам не продемонстрировал, а только анонсировал. )))
Здравствуйте, Sinclair, Вы писали:
EP>>И что должен показать этот конкретный пример? S>То, что практических случаев, когда кэш результатов внутри СУБД будет полезен, можно пересчитать по пальцам. Задней ноги. Лошади.
Допустим что это так, но твой пример это не демонстрирует.
Здравствуйте, gandjustas, Вы писали:
_>>Потому что говоришь о притеснение кэшем памяти отведённой под таблицы. ))) В то время как на практике это совсем разные числа. G>Числа может быть и разные, а память то одна. Каждые 4кб памяти скушанной кешем или еще чем-то приводят к дополнительным чтениям с диска. Ты с этим споришь?
Ну так если истратив 4 Киб мы при этом позволим в большинстве случаев не просматривать 4 МиБ, то это только ускорить систему.
G>Да что ты? А какая? В корпоративных приложениях обычно crudl и большая часть запросов — получение списка (кешировать бесполезно, так как отдаваемые данные сосуществуют покрывающему индексу), на вором месте просмотр сущности (как раз выбор по id, что тоже бесполезно кешировать ибо совпадает с кластерным индексом). Даже если взять консьюмерские мобильные приложения, то они в бекэнде имеют базу и большая часть запросов идет с фильтром по userid. Естественно у каждого пользователя разный userid.
Вообще то выборка из кэша существенно быстрее даже обращения по индексу, т.к. там как минимум не происходит разбора sql и т.п.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, gandjustas, Вы писали:
G>>>>Тогда специально для тебя еще раз объясняю. Задача СУБД — оптимизировать чтение с диска. EP>>>1. Одна из задач, далеко не единственная. Причём это низкоуровевая постановка задачи, а высокоуровневая звучит как — оптимизировать скорость доступа к данным. G>>Данные лежат на диске если что.
EP>Релевантные данные могут полностью находится в памяти.
А могут и не находится. И чем больше база, тем выше вероятность второго случая. Современные движки, при построении планов вовсе не учитывают есть данные в памяти или нет, воспринимая каждое чтение как чтение с диска. И в общем оказываются правы.
G>>Время раундтрипа до базы окажется выше разницы между отдачей результата из кеша и из страниц в памяти. Даже при высоком hit ratio.
EP>1. На обработку данных может понадобится десятки миллисекунд. Например для dummy пробежки одним ядром по ста магабайтам требуется около десяти миллисекунд. Roundtrip может быть намного меньше.
Никто в здравом уме по сотням мегабайт не бегает кадыйм запросом. Используют материализоанные индексы. И, внезапно вместо 100 мб надо обработать 100 кб.
EP>2. Даже если roundtrip намного больше, то всё равно есть преимущество — процессор/память базы не нагружается, соответственно больше свободных ресурсов для обработки других задач. То есть даже при большом latency всё равно для хорошего throughput много применений
А кеш значит бесплатен? Хранение результатов и поиск по ключу ничего не стоят, так?
G>>>>Чтение одной "страницы" занимает 5-10 мсек, EP>>>Это HDD, причём в случае случайного доступа — если же грузится пачка последовательных страниц, то намного меньше G>>А у тебя есть уверенность, что тебе нужна последовательная пачка? EP>Конечно же нет — но это не повод выдавать частные утверждения за общие.
Если что мы говорим о средних значениях. Рассматривать точечные смысла нет.
G>>Станицы в файле данных обычно выделяются случайным образом, так как выделяется только первая свободная. EP>А разве СУБД не старается положить страницы таблицы рядом? Например те же extent'ы.
Старается, но это далеко не всегда возможно.
EP>>>Для БД также используют SSD. G>>И что? EP>А то что для SSD чтение рандомной страницы будет как минимум в разы быстрее.
И что? Все равно чтение с диска — медленная операция.
EP>Даже для обработки сотен мегабайт, что совсем немного по меркам современных объёмов RAM — требуется десятки миллисекунд (одним ядром), а никакие не "доли"
Никто в здравом уме не делает запросов, которые должны в реальном времени лопатить сотни мегабайт. При таких запросах даже кэш не поможет, скорее даже мешать будет. Так как при малейшем изменении запроса (другая дата в параметре) надо будет по новой по таблице бегать и сохранять ответ в ОП, отбирая память у buffer pool.
EP>>>А что тут "не доказано"? То что закэшированный запрос по данным в памяти может отличаться не на доли миллисекунд от обычного обхода (утверждение №1)? Вроде очевидно G>>Также очевидно, что память скушанная кешем приведет к повышению количества чтений с диска. Но тебе почему-то неочевидно.
EP>Это очевидно, но только для некоторых случаев. Я привел конкретные контрпримеры где количество чтений будет меньше — и ты даже согласился, как минимум в случае агрегирования. EP>Речь о том, что не нужно делать чрезмерно общие заявления, справедливые только для некоторых частных случаев.
Вообще-то ты пытаешься обобщить. Если в точечном случае автокэш в базе может быть эффективен для запросов с агрегатами, то это вовсе не означает что кэш будет эффективен. Как минимум нужно понимать hit ratio, а для этого нужно понимать вероятности распределения запросов. Но вот незадача, автокэш не учитывает эти вероятности, так что в среднем он будет неэффективен.
Ты до сих пор этого не понял?
G>>Также очевидно что при равной вероятности любых запросов hit ratio будет нулевым и кеш по факту не будет работать, а при неравномерном распределении та же проблема решается индексами. Но тебе это тоже неочевидно. EP>Конечно это не очевидно, так как контрпример строится элементарно.
Давай, вперед. Желательно с доказательствами твоих слов.
G>>Причем этим очевидным вещам ты противопоставляешь чисто теориетические выкладки. Приведи хоть один результат тестов, который подтверждает твои слова.
EP>Опять таки, хотя бы на счёт агрегации ты согласился, так? Тогда зачем тест?
Ты не понимаешь чем точечная характеристика отличается от средней? Ты же понимаешь, что нельзя судить о средней скорости движения, по тому как сильно ты нажал педальку в один момент. Или нет?
EP>Или ты всё же считаешь что это практически не осуществимо? Если так, то что мешает?
Автоматический кэш в базе, который добавлет быстродействия системе в среднем, практически не осуществим. Потому что у него банально hit ratio будет настолько низкий, что разницы ты не увидишь.
EP>>>То есть без практических примеров ты не можешь понять утверждение №1? G>>Понять != поверить. EP>Поясни. Что конкретно тебе понятно, и во что ты "не веришь" для утверждения №1?
Объясняю еще раз. Я не верю твоим словам о том, что автокэш в базе может быть эффективен. У тебя доказательств обратного нет, ты тупо теоретизируешь.
EP>Аргументы либо верные, либо нет — разница в опыте тут совершенно ортогональна.
Твои аргументы недоказанные. Я не буду даже пытаться их опровергать. Просто буду их игнорировать, пока ты сам не докажешь их верность, ок?
Не пиши больше без результатов тестов.
Здравствуйте, gandjustas, Вы писали:
_>>Это был просто пример, а не универсальное решение. Ещё раз повторюсь: сделать универсальное оптимальное решение невозможно. Однако сделать это для конкретной задачи и БД нет никаких проблем. G>Тем не менее у авторов Linq получилось сделать универсальный типизированный api для доступа к данным. Оптимальность его вызывает сомнения, но накладные расходы компенсируются высокой эффективностью сгенерированных запросов.
С первой частью утверждения согласен. А вот насчёт компенсации высокой эффективностью запросов всё очень сомнительно. ) Собственно говоря в большинстве случаев по сути только один вид запроса и возможен. Ну и даже если в каком-то редком случае возникнет мегасложный запрос, который можно сформулировать существенно по разному, то откуда такая вера, что только linq может выбрать оптимальный вариант? )
_>>А вот IQueryable — это как раз попытка сделать универсальное решение. Более менее конечно же работает, но естественно будет всегда хуже частных решений. G>С чего ты взял что "всегда хуже"? Ты не смог лучше ничего показать, есличо.
А мы разве уже разбирали хотя бы один конкретный частный случай? )
G>На практике ровно наоборот, самописные методы типа GetUser прекрасно заменяются ORM, так еще и эффективность приложения повышают. А Linq2DB умудряется даже банальный мэппинг делать быстрее, чем врукопашную написанный. Ты видимо никогда не делал приложения, работающие с данными раз говоришь такие глупости.
У тебя какая-то мистическая вера в том, что некий простенький транслятор всегда генерирует sql код лучше человека. ) Даже забавно такое слышать. )
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, gandjustas, Вы писали:
EP>>>Здесь под динамическими фильтрами и предикатами — подразумеваются выражения неизвестные во время сборки приложения. Их "специальность" в том, что для них нельзя построить индексы заранее, а не в том что у них какой-то особенный синтаксис. G>>Ты предполагаешь, что любой запрос равновероятен? EP>Необязательно.
Да или нет?
Если да, то кэш в базе не поможет. Если нет, то помогут в первую очередь индексы.
G>>Тогда чем поможет кеш?
EP>Закэширует равновероятные запросы (которые помечены например как "result cache").
То есть всетаки ручной кэш? Тогда зачем его держать в базе? Sinclair наглядно показал бесполезность этого подхода.
G>>А если не равновероятен, то в чем проблема построить индексы?
EP>1. Например акцент распределения меняется со временем — индекс сегодня подходящий для 95%, завтра может подходить лишь для 5% запросов.
Ну ок, поменяй индексы. Это не проблема. А вот поправить программу, которая говорит базе какие результаты кешировать, а какие нет — сложнее.
Так что кэш в базе и с точки зрения удобства использования оказывается хуже.
EP>2. Другой пример: ок, выделили 80% типичных запросов, построили для них индексы — но под остальные запросы они никак не подходят, и паттерны доступа там меняются со временем. Так вот, кэши могут ускорить оставшиеся 20%, чтобы они повторно не грузили систему.
Ты говоришь об автокеше или о ручном? Если ты кешируешь все, то hit ratio низкий и кеш бесполезен. Если ты кешируешь выборочно, то твой кеш будет ориентироваться на те же вероятности. Только когда паттерны доступа изменятся (что на практике не происходит само по себе), то твой выборочный кеш потребует пересборки приложения, а индексы в базу добавить проблем нет.
EP>3. Набор покрывающих индексов может оказаться слишком дорог. Причём даже если не брать в рассмотрение место на дисках, то они отнимают RAM, что увеличивает чтения с диска — так как для разных "индексированных" запросов требуются разные индексы, и помимо этого требуется сама таблица для менее частых (но всё же актуальных) "не индексированных" запросов.
Ты всетаки считаешь что запросы равновероятны? Если нет, то зачем делать много индексов?
S>>>>Индексированное представление — один из хороших вариантов сделать "прикладное кэширование", показав базе, какие производные данные мы ожидаем часто видеть в запросах. EP>>>Как создать индекс для динамических формул? G>>Нету в SQL динамических формул, они все для СУБД одинаковые. EP>С точки зрения зрения приложения они динамические, так как не известны на этапе компиляции.
Все равно для субд они все одинаковые.
Здравствуйте, Sinclair, Вы писали:
S>Непрерывный facepalm. S>SQL — одно из гениальнейших изобретений, в моём личном hall of fame идёт сразу после концепции "вызов подпрограммы". S>Проблема его — в том, что его так и не развили до полноценного языка программирования, не дав средств управления сложностью. S>В рамках одного запроса он непревзойдён — встроенную в него механику вывода типов десятилетиями не удавалось догнать в промышленных языках программирования. S>(Вот я, к примеру, до сих пор не вполне понимаю, каким образом эту проблему решает sqlpp). В основном из-за этого и сосали все основные ORM — они пытались уложить выразительную систему реляционных типов, существующую в SQL, в убогую модель номинативной типизации. Из-за этого и получались все эти "недозагруженные user" и прочий бред.
Я тут уже спрашивал у других собеседников... Чем нам поможет гениальный sql в случае скажем работы с графами? ) А это очень часто встречающаяся вещь — деревья с данными, настройками и т.п. чуть ли не в каждом приложение есть. Это не говоря уже о файловых системах, реестрах и т.п.
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, gandjustas, Вы писали:
G>>В деньгах? Огромный. Например в одном банке (не могу назвать в каком по причине NDA) своя разработка кушает не более 5% ИТ бюджета, а услуги внешних компаний — около 20%. Причем в баках реально большие расходы на ИТ, в остальных отраслях соотношение еще меньше.
_>Так мы же не про деньги говорили, а про количество программистов. )))
Тем более. В яндексе, ЛК, майлру суммарно работает больше чем во всех банках вместе взятых. А если еще посчитать интеграторов...
Банально взгляни вакансии на HH. Большая часть это софтовые конторы и корп. разработка.
_>>>В C# может и нет, а в других языках есть. Что тебе тут и продемонстрировали. Просто ты этого упорно не хочешь признавать. G>>Это ты веришь что они есть. А я не увидел ничего близкого по функционалу по сравнению с тем, что было в моих приложениях.
_>Ну ну) Пока что единственное, что тебе не продемонстрировали (причём это не означает, что с этим есть какие-то проблемы), это переброску запроса между dll. Но кстати говоря это ты и сам не продемонстрировал, а только анонсировал. )))
И это значимое различие. В .NET любой экземпляр любого типа может спокойно передаваться в другую сборку, так что даже демонстрировать не буду. Если хоть немного .net знаешь,то даже писать бы такое не стал.
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, gandjustas, Вы писали:
_>>>Потому что говоришь о притеснение кэшем памяти отведённой под таблицы. ))) В то время как на практике это совсем разные числа. G>>Числа может быть и разные, а память то одна. Каждые 4кб памяти скушанной кешем или еще чем-то приводят к дополнительным чтениям с диска. Ты с этим споришь?
_>Ну так если истратив 4 Киб мы при этом позволим в большинстве случаев не просматривать 4 МиБ, то это только ускорить систему.
С чего ты взял что в большинстве? Если кеш не учитывает распределение запросов, то его hit ratio будет крайне низок и в среднем вряд ли ускорит приложение. Только в примитивных случаях (один клиент и малое количество запросов) может помочь. А если ты о ручном кеше, то его лучше отдельно делать и интегрировать с кешем на клиенте.
G>>Да что ты? А какая? В корпоративных приложениях обычно crudl и большая часть запросов — получение списка (кешировать бесполезно, так как отдаваемые данные сосуществуют покрывающему индексу), на вором месте просмотр сущности (как раз выбор по id, что тоже бесполезно кешировать ибо совпадает с кластерным индексом). Даже если взять консьюмерские мобильные приложения, то они в бекэнде имеют базу и большая часть запросов идет с фильтром по userid. Естественно у каждого пользователя разный userid.
_>Вообще то выборка из кэша существенно быстрее даже обращения по индексу, т.к. там как минимум не происходит разбора sql и т.п.
Изучай как базы работают. Разбор sql делается один раз при построении плана, план потом из кеша достается.
Короче ты с каждым сообщением доказываешь что не понимаешь ни СУБД, ни архитектуру приложений. Не надоело? Все и так уже поняли.
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, gandjustas, Вы писали:
_>>>Это был просто пример, а не универсальное решение. Ещё раз повторюсь: сделать универсальное оптимальное решение невозможно. Однако сделать это для конкретной задачи и БД нет никаких проблем. G>>Тем не менее у авторов Linq получилось сделать универсальный типизированный api для доступа к данным. Оптимальность его вызывает сомнения, но накладные расходы компенсируются высокой эффективностью сгенерированных запросов.
_>С первой частью утверждения согласен. А вот насчёт компенсации высокой эффективностью запросов всё очень сомнительно. ) Собственно говоря в большинстве случаев по сути только один вид запроса и возможен. Ну и даже если в каком-то редком случае возникнет мегасложный запрос, который можно сформулировать существенно по разному, то откуда такая вера, что только linq может выбрать оптимальный вариант? )
Linq не выбирает варианты запросов, он просто генерирует что ему сказали. Но у linq есть средства дкомпозиции, а у SQL нет.
Представь что ты бы писал на языке, на котором нет функций, то есть ты все должен сделать в одной функции main, а потом у тебя появилась возможность разбивать программу на функции, сможешь писать более сложные программы после этого? Очевидно да. Та же ситуация с linq.
_>>>А вот IQueryable — это как раз попытка сделать универсальное решение. Более менее конечно же работает, но естественно будет всегда хуже частных решений. G>>С чего ты взял что "всегда хуже"? Ты не смог лучше ничего показать, есличо. _>А мы разве уже разбирали хотя бы один конкретный частный случай? )
Стой, ты уже утверждаешь, что "всегда хуже". То есть в любом частном случае ты подберешь вариант лучше linq.
Ты уже не смог это сделать, зачем дальше обсуждать?
G>>На практике ровно наоборот, самописные методы типа GetUser прекрасно заменяются ORM, так еще и эффективность приложения повышают. А Linq2DB умудряется даже банальный мэппинг делать быстрее, чем врукопашную написанный. Ты видимо никогда не делал приложения, работающие с данными раз говоришь такие глупости.
_>У тебя какая-то мистическая вера в том, что некий простенький транслятор всегда генерирует sql код лучше человека. ) Даже забавно такое слышать. )
Ты написал sql с помощью склейки строк и пропустил там sql-инъекцию. Ты сам прекрасно продемострировал, что linq сработал лучше человека. Почему продолжаешь спорить?
А также помни, что в linq есть средства декомпозиции, которые позволяют строить более сложные запросы, чем человек сможет осилить.