А можно какие то пруфы данного утверждения? Просто если с подзапросами я согласен, то join при правильном проектировании БД обычно проблем не вызывает. Обычно на мускуле самая большая проблема group by. Уже на 20млн записей посчитать статистику становится проблемой
Сейчас погуглил, не нашел подтверждению пункту 1, так что можно его считать не актуальным. Если не хочется возиться с новой технологией можно рассмотреть вариант репликации master/slave. Пишем в master читаем со slave. Правда при большом объеме модификаций возможно отставание реплик. В 5.7 появился cluster https://dev.mysql.com/doc/refman/5.7/en/faqs-mysql-cluster.html
Насколько я понимаю обычно путь джедая к светлой стороне такой
1) Замена update -> insert & delete
2) Если первый пункт не помог, аккумулирование изменений в очереди/кэше и отложенный multi insert/ multi update
3) Если же объем модифицирующих запросов на столько велик, что ничего не помогло, надо уходить с MySQL. Здесь сложно что то посоветовать куда уходить. Для примера можно посмотреть Cassandra, Click House итд
Repository + Entity — driven db access в 100% наблюдаемых мною случаев превращается в непригодный к дальнейшему использованию legacy код.
Если репозиторий не нагружать лишними функциями, то вполне себе рабочий вариант. Репозиторий должен кэшировать результаты и выполнять запросы в базу. Все остальное лишнее. Мне кажется куда более часто встречающаяся проблема это увлечение god object и не умение найти баланс в делении кода на атомарные логические сущности
Ок. Давайте посмотрим цитаты из Ваших ссылок
1) This advice does not apply to large structs, or even small structs that might grow.
2) If variable is a large struct and performance is an issue, it's preferable to pass variable by pointer. So that to avoid expensive copying of the whole struct in memory.
Естественно, передавать int по ссылке бессмысленно. Но, если реализовывать нормальный dependency injection, то передача по ссылке критична. Кроме того, у меня сложилось мнение что в golang при возврате значения нет move семантики и поэтому возвращать из функции, аналога конструктора, лучше тоже ссылку
Давайте рассмотрим пример. Вот есть С++ проект https://github.com/BVLC/caffe (нейросети). Под linux/osx master ветка. Под windows создана отдельная ветка поддерживаемая microsoft причем вангую что ветка под windows никогда не попадет в master. В master ветке сборка идет через make или cmake. В windows ветке сборка идет через cmake/ninja. Управление зависимостями тоже не универсально. Под linux apt-get с перечислением зависимостей вручную. Под osx mac ports с перечислением зависимостей вручную. Под винду вообще python скрипт скачивающий prebuilt зависимости (https://github.com/BVLC/caffe/blob/windows/scripts/download_prebuilt_dependencies.py). Более того, если посмотреть список полученных зависимостей, то во-первых часть из них .lib, а часть с расширением .a (что говорит о сборке через cygwin), а во вторых часть статических библиотек идет с префиксом lib часть без. По мне так это называется бардак, который сказывается на том, что большую часть времени приходится заниматься сборкой, а не собственно программированием. При этом во многих языках эти проблемы решили. Взять например cargo, или на худой конец npm. Тот же Go при всех его недостатках если не использовать cgo гарантированно соберется на osx/linux/win без дополнительных танцев с бубном
На самом деле я так и не нашел совсем правильного варианта как это должно выглядеть. Вот предположим у меня есть 3 сервиса, 10 моделей, 10 контроллеров. Получается что под каждую сущность мне нужно создавать отдельный пакет и их всех положить в соответствующую папку внутри vendor? Более того чтобы проект оставался go get'able под каждую сущность нужен свой репозиторий?
Смотрите, любая передача данных в функцию возможна в go только по значению или по ссылке. Естественно передача по ссылке более быстрая чем по значению, но при этом пометить, что значение переданное по ссылке менять нельзя, возможности нет
В C++ на мой взгляд на текущий момент самая большая проблема это система сборки и отсутствие единого пакетного менеджера. В результате каждая сборка крупного проекта на C++ приносит новую порцию "радости". Особенно чувствуется когда надо собрать проект рассчитанный на, скажем, Ubuntu под Windows. Начинаются всякие пляски с cygwin, mingw итд при том что в целом по синтаксису gcc не сильно отличается от msvc.
Отсюда кстати проистекает еще один минус языка. Вся документация, все примеры негласно сводятся к одной папке содержащей main.go и main_test.go. Если начать разбираться то вылезают следующие ограничения:
1) относительные пути импорта не рекомендуются и могут быть выпилены в будущем
2) импортировать надо относительно GOPATH и названия package либо просто от названия package
3) В одной папке могут быть файлы только одного package
Самое главное почему используют go — это горутины и идущий с ними в комплекте планировщик. Этот планировщик позволяет запустить N горутин на M потоков и скорость полученного решения будет очень высокой, а сложность разработки низкой. Я так понимаю, что даже если в 20 стандарте С++ примут корутины планировщик все равно надо будет дополнительно разрабатывать. Поэтому в идеале было бы здорово иметь go в качестве библиотеки для С++ приносящей скорость и легковесность горутин в C++
Я согласен что нельзя ожидать что в реальных проектах скорость будет такая же как в синтетике. Просто Вы правда считаете что для реального проекта 15 rps/ 1s на ответ это норма?
Я просто к тому что цифры какие-то не серьезные и для Java и для Node.js. К примеру даже на банальном PHP цифры получаются совсем другого порядка. Первая же ссылка в гугле — https://github.com/kenjis/php-framework-benchmark Цифры начинаются от 100 и заканчиваются на 2000 rps. Правильно организованная Java должна брать 2-3k rps
Я понимаю что это перевод и все таки спрошу. Вы сами понимаете смысл цифр в таблице? Я вот например если правильно понял у paypal было около 8 rps а стало около 15rps. Было время ответа около 1с а стало 600-800 мс. Но я все таки надеюсь что я что-то не так понимаю
Хочется хотя бы на пальцах понять на каких объемах и каких индексах у join c 10 таблицами начинаются проблемы
А можно какие то пруфы данного утверждения? Просто если с подзапросами я согласен, то join при правильном проектировании БД обычно проблем не вызывает. Обычно на мускуле самая большая проблема group by. Уже на 20млн записей посчитать статистику становится проблемой
Сейчас погуглил, не нашел подтверждению пункту 1, так что можно его считать не актуальным. Если не хочется возиться с новой технологией можно рассмотреть вариант репликации master/slave. Пишем в master читаем со slave. Правда при большом объеме модификаций возможно отставание реплик. В 5.7 появился cluster https://dev.mysql.com/doc/refman/5.7/en/faqs-mysql-cluster.html
Насколько я понимаю обычно путь джедая к светлой стороне такой
1) Замена update -> insert & delete
2) Если первый пункт не помог, аккумулирование изменений в очереди/кэше и отложенный multi insert/ multi update
3) Если же объем модифицирующих запросов на столько велик, что ничего не помогло, надо уходить с MySQL. Здесь сложно что то посоветовать куда уходить. Для примера можно посмотреть Cassandra, Click House итд
Если репозиторий не нагружать лишними функциями, то вполне себе рабочий вариант. Репозиторий должен кэшировать результаты и выполнять запросы в базу. Все остальное лишнее. Мне кажется куда более часто встречающаяся проблема это увлечение god object и не умение найти баланс в делении кода на атомарные логические сущности
Ок. Давайте посмотрим цитаты из Ваших ссылок
1) This advice does not apply to large structs, or even small structs that might grow.
2) If variable is a large struct and performance is an issue, it's preferable to pass variable by pointer. So that to avoid expensive copying of the whole struct in memory.
Естественно, передавать int по ссылке бессмысленно. Но, если реализовывать нормальный dependency injection, то передача по ссылке критична. Кроме того, у меня сложилось мнение что в golang при возврате значения нет move семантики и поэтому возвращать из функции, аналога конструктора, лучше тоже ссылку
А можно какой-нибудь пруф данного утверждения?
Давайте рассмотрим пример. Вот есть С++ проект https://github.com/BVLC/caffe (нейросети). Под linux/osx master ветка. Под windows создана отдельная ветка поддерживаемая microsoft причем вангую что ветка под windows никогда не попадет в master. В master ветке сборка идет через make или cmake. В windows ветке сборка идет через cmake/ninja. Управление зависимостями тоже не универсально. Под linux apt-get с перечислением зависимостей вручную. Под osx mac ports с перечислением зависимостей вручную. Под винду вообще python скрипт скачивающий prebuilt зависимости (https://github.com/BVLC/caffe/blob/windows/scripts/download_prebuilt_dependencies.py). Более того, если посмотреть список полученных зависимостей, то во-первых часть из них .lib, а часть с расширением .a (что говорит о сборке через cygwin), а во вторых часть статических библиотек идет с префиксом lib часть без. По мне так это называется бардак, который сказывается на том, что большую часть времени приходится заниматься сборкой, а не собственно программированием. При этом во многих языках эти проблемы решили. Взять например cargo, или на худой конец npm. Тот же Go при всех его недостатках если не использовать cgo гарантированно соберется на osx/linux/win без дополнительных танцев с бубном
На самом деле я так и не нашел совсем правильного варианта как это должно выглядеть. Вот предположим у меня есть 3 сервиса, 10 моделей, 10 контроллеров. Получается что под каждую сущность мне нужно создавать отдельный пакет и их всех положить в соответствующую папку внутри vendor? Более того чтобы проект оставался go get'able под каждую сущность нужен свой репозиторий?
К любому синтаксису можно привыкнуть. Когда я изучал Rust было очень не привычно видеть конструкции вида
Особенно тяжело было смириться с плюсом в типе переменной))) Но со временем привыкаешь и становится даже удобно
Смотрите, любая передача данных в функцию возможна в go только по значению или по ссылке. Естественно передача по ссылке более быстрая чем по значению, но при этом пометить, что значение переданное по ссылке менять нельзя, возможности нет
Тут давеча в обсуждении высказывали гипотезу что при вызове через cgo может создаваться отдельный поток (https://habrahabr.ru/company/mailru/blog/324250/#comment_10129248) Я не берусь сказать насколько это правда.
В C++ на мой взгляд на текущий момент самая большая проблема это система сборки и отсутствие единого пакетного менеджера. В результате каждая сборка крупного проекта на C++ приносит новую порцию "радости". Особенно чувствуется когда надо собрать проект рассчитанный на, скажем, Ubuntu под Windows. Начинаются всякие пляски с cygwin, mingw итд при том что в целом по синтаксису gcc не сильно отличается от msvc.
Отсюда кстати проистекает еще один минус языка. Вся документация, все примеры негласно сводятся к одной папке содержащей main.go и main_test.go. Если начать разбираться то вылезают следующие ограничения:
1) относительные пути импорта не рекомендуются и могут быть выпилены в будущем
2) импортировать надо относительно GOPATH и названия package либо просто от названия package
3) В одной папке могут быть файлы только одного package
Да, спасибо за поправку, имелись ввиду неизменяемые ссылки на переменные
Самое главное почему используют go — это горутины и идущий с ними в комплекте планировщик. Этот планировщик позволяет запустить N горутин на M потоков и скорость полученного решения будет очень высокой, а сложность разработки низкой. Я так понимаю, что даже если в 20 стандарте С++ примут корутины планировщик все равно надо будет дополнительно разрабатывать. Поэтому в идеале было бы здорово иметь go в качестве библиотеки для С++ приносящей скорость и легковесность горутин в C++
Еще очень сильно убивает отсутствие модификатора const для переменных
Я согласен что нельзя ожидать что в реальных проектах скорость будет такая же как в синтетике. Просто Вы правда считаете что для реального проекта 15 rps/ 1s на ответ это норма?
Я просто к тому что цифры какие-то не серьезные и для Java и для Node.js. К примеру даже на банальном PHP цифры получаются совсем другого порядка. Первая же ссылка в гугле — https://github.com/kenjis/php-framework-benchmark Цифры начинаются от 100 и заканчиваются на 2000 rps. Правильно организованная Java должна брать 2-3k rps
Я понимаю что это перевод и все таки спрошу. Вы сами понимаете смысл цифр в таблице? Я вот например если правильно понял у paypal было около 8 rps а стало около 15rps. Было время ответа около 1с а стало 600-800 мс. Но я все таки надеюсь что я что-то не так понимаю