There will be no singularity – Telegram
There will be no singularity
1.99K subscribers
248 photos
15 videos
5 files
995 links
Smartface, technologies and decay
@antonrevyako
Download Telegram
«Прежде всего, дзен Python говорит, что любое решение должно быть единственное. Поэтому в Python всего минимум по три.»
Пока ты учишь хаскель, гуманитарии прикидываются программистами...

«... Поэтому мы запускаем маркетплейс заказов по No-code, где клиенты могут разместить запрос на разработку проекта, а ноукодеры и агентства откликнуться и получить поток заказов.»

https://news.1rj.ru/str/Ogurzy/496
Пока космические корабли бороздят (зачеркнуто) postgresql становится быстрее с каждым новым релизом, монга становится медленнее:


https://www.percona.com/blog/2020/06/24/evaluating-mongodb-under-python-tpcc-1000w-workload/
Пора признаться, что мы запустили в режиме раннего тестирования holistic.dev - инструмент для автоматического поиска проблем в SQL-запросах и архитектуре баз данных!

Что это такое?
Holistic.dev - это статический анализатор в виде SaaS. Скорее всего вы уже используете статические анализаторы в классических языках программирования. Но для SQL таких инструментов нет.
Мы нашли способ извлечения знаний о структуре связей между данными во всем вашем проекте на основе схемы базы данных и наборе SQL-запросов. Эти знания позволяют нам автоматически следить за согласованностью существующих связей и предоставлять инструменты для автоматического поиска проблем.


Кому это нужно?
Всем, кто думает о производительности и архитектуре своей базы данных. Обычно, больше всего это заботит DBA :) Но DBA есть не во всех компаниях, и довольно часто вопросами производительности приходится заниматься разработчикам.

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

Если вам повезло и вы пишите на чистом SQL, то, во-первых, вы можете отправлять запросы на анализ не дожидаясь проблем в продакшене еще на этапе разработки и/или в CI, а во-вторых, кроме проблем с производительностью запросов вам так же пригодятся подсказки по улучшению архитектуры базы и упрощению запросов. Это позитивно влияет на скорость онбординга новых сотрудников, повышение общего уровня SQL-разработчков, и уменьшение time-to-market.


Что умеет наш инструмент?
Умеет анализировать схему базы данных и запросы. НЕ ТРЕБУЕТ ПРЯМОГО ПОДКЛЮЧЕНИЯ К БАЗЕ И НЕ ИМЕЕТ ДОСТУПА К ДАННЫМ!
Работает только на исходных текстах запросов, которые пользователь присылает самостоятельно.

Расскажет о том, что можно улучшить в схеме базы данных (DDL) и в каждом из запросов (DML). На данный момент реализовано 70 правил, которые включают, например, рекомендации из Don't Do This. Умеет находить колонки в условиях в WHERE, которые не встречаются в индексах.

Знает какие типы у полей будут в результате выполнения и могут ли там появиться NULL-значения, даже если эти поля являются результатом вычислений или сложных JOIN.
Знает, сколько строк вернет запрос (!!!) :) Нет, конечно не в точных цифрах, а в категориях none, one, one or none, many or none.
Для тех, кто пишет на чистом SQL, это поможет сравнить типы и ожидаемое количество строк в приложении с типами результатов выполнения запросов без тестов, код ревью и дебага :)

На данный момент поддерживается синтаксис Postgresql до 13 версии включительно.
Понимает схемы, таблицы, вьюхи, все core функции и операторы, пользовательские функции и операторы, знает про много разных расширений (extension).

В пару простых операций можно автоматизировать экспорт запросов непосредственно из боевой базы, и получать извещения о найденых проблемах при их появлении.
Это возможно сделать как на on-premise установках, так и в managed базах (AWS RDS, Yandex.Cloud, Digital Ocean и тд). В ближайшее время мы подготовим FaaS для основных cloud-провайдеров.
Чего наш инструмент не умеет?
Т.к. мы не имеем доступ к вашей базе, мы ничего не знаем о ее настройке, не можем выполнить EXPLAIN или помочь с настройкой репликации.
Мы не касаемся ничего, что относится к операционной деятельности. Для анализа метрик базы уже существует много инструментов, и они довольно неплохи.

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


Ближайшие планы
- Больше правил. На данный момент в продакшене 70 правил из 1300+, которые лежат в беклоге.
- Удобный интерфейс просмотра и расширенного поиска истории метрик из pg_stat_statements (если вы настроите автоматическую отправку ваших метрик)
- Автоматическое обновление DDL. Даст возможность автоматически поддерживать состояние схемы базы данных в нашем сервисе в актуальном состоянии.
- Экспорт типов результатов запросов. Можно использовать для генерации кода ваших приложений или для проверки соответствия типов между приложением и запросами в CI
- Список run-time исключений, которые может выбросить запрос. Например, из-за нарушений уникальности индекса или ошибочного приведения типов.
- Экспорт объекта, отражающего состояние схемы базы. Можно использовать для документации или, например, миграциий.
- Больше поддерживаемых расширений (extension)
- доставка уведомлений о найденных проблемах на email/slack


Сколько это стоит?
Нисколько. Пока все бесплатно. Мы хотим собрать отзывы о нашем продукте, прежде чем запустить его в коммерческую эксплуатацию.


Что взамен?
Мы ищем компании для бесплатных пилотных внедрений.
Внедрение автоматической доставки запросов со стороны базы занимает не больше часа. После этого сразу станет возможным просматривать найденные проблемы в личном кабинете.


Как подключиться?
На holistic.dev вы можете попробовать инструмент в playground на заранее подготовленных демо базах или на любых своих запросах.
Зарегистрировавшись, вы получаете возможность создать несколько проектов, загрузить схемы баз и автоматизировать доставку запросов из базы через API.

На все вопросы, предложения и ругань с удовольствием отвечу в телеграме @antonrevyako или с почты info@holistic.dev


Ваш анализатор ничего не нашел!
Да, такое возможно. Вы молодец!
Но это не точно :) На данный момент реализовано 5% от описанных правил, и довольно вероятно, что позже мы что-то сможем обнаружить. Оставайтесь с нами и мы автоматически пришлем отчет, если новые правила все же найдут проблемы в ваших запросах.
Forwarded from Neural Shit
Лол, чувак завёл блог, в который постил выдачу нейросети GPT-3. За две недели этот блог набрал 26 тысяч посетителей и почти никто не заметил подвоха. Те же, кто предположил в комментариях, что текст синтетический — были заминусованы другими читателями. Киберпанк, который мы заслужили.
Подробнее тут (на языке вероятного противника)
Спешу дополнить пост про необычные места, в которые догадались засунуть SQL (https://news.1rj.ru/str/nosingularity/493) еще одним пунктом:

5) gitqlite is a tool for running SQL queries on git repositories
https://github.com/augmentable-dev/gitqlite

-- how many commits have been authored by user@email.com?
SELECT count(*) FROM commits WHERE author_email = 'user@email.com'
Если вы имеете привычку смотреть сериалы, но по какой-то причине еще не видели The Umbrella Academy, то предлагаю потратить эти выходные на сабж.
Особенно прекрасно, что недавно Netflix выложил второй сезон.
А пока до выходных остаются сутки, можно послушать OST из второго сезона
Или OST из первого
https://news.1rj.ru/str/oleg_log/3454

Про отсутствие централизованного репозитория сломано много копий.

Захотелось мне как-то собрать cockroachdb . И я не смог собрать :(

Ни из мастера, ни из специального архива из документации, где должна быть стопудово работающая версия.
Не хватает каких-то пакетов.
Может репы стали приватными, хз.

Я бы прям подписался на канал с видосами - «собираем известные golang проекты из ветки master»
Сколько времени занимает создание правила для статического анализатора?

В holistic.dev есть 3 группы правил - performance, architect, security.

Часть из этих правил имеют простую природу и срабатывают на основании структуры абстрактного синтаксического дерева.
Подобным образом работают линтеры. Например, eslint для javanoscript.

Такие правила писать легко и быстро и за день можно сделать пяток. Но, писать их скучно :)
Например, правило, рекомендующее избегать конструкций WHERE TRUE или JOIN ON TRUE

Правила, которые основываются на знании о типах и ограничениях, возникающих в момент выполнения запроса писать намного увлекательнее. Но и времени это занимает прилично. Особенно, когда это правило касается производительности.

Сегодня я расскажу вам про правило, на которое я собирался потратить не более 30 минут, но потратил гораздо больше...

Я не очень люблю писать performance-правила. Приходится гонять много тестов в разных окружениях и подбирать ссылки на материалы, которые потом попадут в детальное описание правила. Туда же должны попасть пруфы - запросы, которые вы можете выполнить сами, чтобы убедиться в том, что рекомендация дана по делу.

Есть крайне противоположные мнения относительно рекомендаций по улучшению производительности. Одно - "Анализатор расскажет мне про отсутствующие индексы и я их сразу сделаю". Второе - "Когда начнет тормозить, мы это заметим и поправим. Преждевременная оптимизация — зло!".
Но правда, как обычно, где-то посередине.

Действующие лица: я, функция count, stackoverflow.

Скорее всего вы знаете, что функция count - опасная штука. Она перебирает все поля в таблице (seq scan), чтобы выдать точное количество строк. И это может занимать неприличное время на больших таблицах. Ускорить count можно несколькими способами, которые больше зависят от бизнес-процессов, чем от конкретного запроса.

К слову, сейчас про count описано почти 2 десятка правил и часть из них уже в проде.

Функция count имеет 2 основных применения:
- count(*) или count(любая константа) считает общее количество строк. Кстати, в postgresql count(*) работает быстрее, чем count(1)
- count (колонка или выражение) считает количество значений, отличных от NULL

Но иногда хочется посчитать не просто количество не-NULL значений, а количество уникальных значений.
Для этого можно не задумываясь использовать count(DISTINCT a). Но есть нюанс...
Такой запрос запросто будет МИНИМУМ в 10 раз медленнее.

Оно и понятно. Нужно взять все строки, найти уникальные, и только потом сосчитать их.
Что тут можно сделать? Как минимум, предупредить разработчика о таком неприятном факте, т.к. проблему с запросом он заметит скорее всего не скоро.

А можно ускорить? Вообще-то да. DISTINCT всегда работает медленнее, чем GROUP BY, поэтому, возможны ситуации, где можно сначала сгруппировать данные, а потом посчитать их количество.
Будет как-то так:
SELECT count (*) FROM (SELECT a FROM t GROUP BY a) t1


Даже можно уникальные по нескольким полям считать, не то что с DISTINCT.
Нормально, Григорий! Отлично, Константин!

Так... надо подготовить ссылки и пруфы. Окей, гугл, postgresql select disctinct...

https://stackoverflow.com/questions/11250253/postgresql-countdistinct-very-slow

Ну! А я о чем говорил?! Только тут ребята про GROUP BY не подумали... Ну да ладно, все кейсы в документации распишу. Потом...

Так, пруфы...
Делаем таблицу, заполняем, камера, мотор...

Запрос c count(DISTINCT a) - 243.630 ms
Запрос c count(*) FROM (SELECT) - 509.572 ms

ЭЭЭЭ.... wat?
А с индексом?
247.845 ms / 291.898 ms

Это как? SO не может врать! 317 votes, "holy queries batman! This sped up my PostgreSQL count distinct from 190s to 4.5 whoa!"

... пропустим пару часов экспериментов с разными версиями базы, таблицами с индексами и без ...
А теперь результаты.
SELECT count(*) FROM (SELECT DISTINCT a ...)
заметно ускоряет запросы, если:
- "a" является строковым полем (VARCHAR/TEXT)
- в качестве параметра count() выступает ROW только из строковых полей -
SELECT COUNT(DISTINCT (a,b))

Если на текстовое поле, по которому делается DISTINCT нет индекса, то
SELECT count(*) FROM (SELECT DISTINCT a ...)
будет МЕДЛЕННЕЕ, чем
SELECT count(DISTINCT a)
, но
SELECT COUNT(*) FROM (SELECT a FROM t GROUP BY a)
будет быстрее.
Причем в индексе нужное поле должно стоять на 1 месте, иначе результат будет аналогичен запросу без индекса.

Если в качестве параметра count() выступает ROW из полей не только строковых типов, то результат также будет аналогичен запросу по текстовому полю без индекса.

Как было озвучено ранее, GROUP BY всегда быстрее DISTINCT. Поэтому, если есть выбор что использовать - используйте GROUP BY.

Для полей других типов (числовые, дата и время) такая "оптимизация" даст отрицательный эффект.

Стоит сгенерировать пруфы для разных типов, collation и прочего, но это все потом...

В зависимости от окружения, количества данных, насильно выключенного seq_scan и других параметров порядок разницы между результатами изменяется. Иногда он не выглядит столь драматично, чтобы стоило об этом переживать. Но все равно результаты укладываются в описанную выше схему.


Какие выводы мы можем сделать из этой истории?
- мы знаем намного меньше, чем нам кажется
- когда копируешь что-то с SO - проверяй на своих кейсах
- не все можно сказать только по самому запросу, многое зависит от типов
- используй статический анализ везде, где сможешь
- линтеры тоже используй, но четко осознавай границы применимости

Итак, сколько времени занимает создание правила для статического анализатора?
Одно правило можно писать несколько дней. Может так выйти, что данных, которые выдает наш парсер недостаточно для реализации некоторых правил. Тогда дорабатывается анализатор. Последний раз такая доработка заняла несколько месяцев.

Я как-нибудь вам обязательно расскажу как понять какие индексы PostgreSQL сможет использовать при выполнении запроса. Это очень интересно....
когда человек говорит, что он фулстек
В посте выше я приводил в пример мнение некоторых менеджеров и разработчиков относительно оптимизации запросов: «Когда начнет тормозить, мы это заметим и поправим. Преждевременная оптимизация — зло!»

Вот история про таких, только уже в виде постмортема :)

https://news.1rj.ru/str/neverendingit/205
2020 набирает обороты.
Все ждали киберпанк 2077 с Киану, а получим... zx spectrum! next! с вайфаем!

Z-80 легендарный процессор. На таких процессорах работал даже коммутатор сотовой компании, в которой я работал 20 лет назад (и где грохнул базу абонентов)

PS: Тот смешной проект по запихиванию андурины в корпус кассеты для загрузки спектрумов уже не выглядит таким смешным...
Рейтинг частотности правил SQL анализатора holistic.dev

За 10 дней прошедших с момента публичного релиза многие из вас откликнулись на призыв протестировать наш сервис, за что вам большое спасибо!
И чтобы как-то отметить эту знаменательную дату (та-дам!), расскажем что же чаще всего мы находили в ваших запросах:

5. like-dynamic-template
4. select-naked
3. de-morgan-laws
2. limit-offset-without-orderby
1. column-not-in-index

К сожалению, у нас нет подробной документации по каждому из правил, поэтому я коротенько расскажу вам про них.

На пятом месте like-dynamic-template (performance/architect)
Такое правило срабатывает в ситуациях, когда в LIKE или ILIKE встречаются динамические значения. Это плохо влияет и на производительность (индекс, даже если он есть не будет использован) и так себе с точки зрения архитектуры.

На четвертом select-naked (performance/architect/security)
Срабатывает, когда у SELECT нет никаких ограничивающих или группирующих условий.
 SELECT a FROM t 
например. Это плохо тем, что будут возвращены значения из всех строк таблицы, что может быть довольно большим объемом данных и это не будет быстро. А во-вторых, что ты такое хранишь в этой таблице, что тебе понадобилось вытащить все данные?

Третье место de-morgan-laws (architect)
Законы де Моргана - это правила раскрытия отрицания в булевой алгебре:
NOT (A OR B) = NOT A AND NOT B
NOT (A AND B) = NOT A OR NOT B
Правило срабатывает, когда встречается отрицание булевых выражений. Почему это может быть проблемой?
В булевой алгебре все немного проще, чем в SQL. NOT это не всегда отрицание в прямом понимании этого слова.
Например, NOT (a IS TRUE) это не a = FALSE, как могло бы показаться. NOT (a IS TRUE) это a = FALSE OR a IS NULL.
Если вы пишете запросы руками, то при дальнейшем чтении понимание таких конструкций будет затруднено.
Избегайте отрицания булевых выражений!

Второе место limit-offset-without-orderby (architect)
Для многих это будет сюрпризом, но в Postgresql нет сортировки по умолчанию. Т.е. порядок строк в результате не гарантирован. Об этом честно написано в документации - "if sorting is not chosen, the rows will be returned in an unspecified order".
Если вы хотите взять первые N строк, то стоит определить порядок, по которому будет понятно где именно находится это самое начало.
На этом месте скорее всего был бы NOTICE select-without-orderby, но он еще не в проде :)

Если в вашем приложении порядок следования строк может влиять я бизнес процессы, крайне рекомендую проверить ваши запросы хотя бы руками (но лучше через holistic.dev)!

И призовое место - column-not-in-index
(performance)
Это, конечно, предсказуемо. Правило срабатывает при нахождении колонок, которые не упоминаются в индексах.
Это не говорит о том, что индексы в запросе не используются. Чтобы ответить на такой вопрос, требуется еще немало поработать (я обещал рассказать об этом в ближайшее время).
Само по себе появление такого issue не смертельно. Возможно, эти колонки используются в фильтрации после применения индекса.
В любом случае обратить внимание на эти колонки не будет лишним. Может быть вы обнаружите действительно проблемные места.
There will be no singularity pinned «Пора признаться, что мы запустили в режиме раннего тестирования holistic.dev - инструмент для автоматического поиска проблем в SQL-запросах и архитектуре баз данных! Что это такое? Holistic.dev - это статический анализатор в виде SaaS. Скорее всего вы уже…»
Любить свое дело (делать с душой)

Я сторонник версии, что свое дело нужно любить. Вот прям любить.
Мне сложно понять подход "Я гребу с 9 до 18 по будням с перерывом на обед. В остальное время программирование меня не интересует".

Меня программирование интересует 24x7. И не только программирование. В любое дело, что я начинал, я погружался с головой.
Да, это опасно. Можно выгореть :) Но иначе - зачем это все?

Я стараюсь идти в бой такими же увлеченными людьми, но в наше время таких людей все меньше.
Сейчас без индивидуального плана развития ты никого не наймешь.
Job hopping раз в 6 месяцев не считается чем-то плохим...

Но сегодня я не хотел об этом бухтеть. Я расскажу вам историю о том, как много лет назад я открыл интернет-магазин.
У меня было много разных проектов и интернет-магазин один из них.

Нет, это не такие интернет-магазины, которые любой человек сегодня может сделать в 2 клика.
Тогда не было дроп-шиппинга. В онлайне почти никто не покупал и приходилось договариваться с оффлайн точками о выкладке.

Мне хотелось сделать что-то веселое. И я решил привести в нашу деревню какие-то прикольные штуки, которые могут стать подарком.
Тогда на рынке подарков локомотивом был "красный куб" с соответствующим ассортиментом.
Я решил торговать странными штуками - профессиональными yo-yo, паверболами и всяким таким. Если вы не знаете что такое yo-oy, посмотрите видео с международных конкурсов. Это отдельная вселенная :)
До сих пор у меня валяется меч из "звездных воин". Вот такой :)

Вокруг магазина сложилась туса со своей атмосферой. С некоторыми из участников я общаюсь до сих пор.

Делать приходилось все, включая маркетинговые материалы. И я обратился к своему старому корешу, чтобы тот нарисовал плакат и флаеры.
Он очень крутой художник, фотограф, видеограф, аниматор и вот это все. К каждому проекту он подходит с душой.
"Я сделаю, но по-своему", - сказал он. Как обычно, в общем-то :) Но я был уверен, что все будет ок.

В то же время у него был проект, который он делал для себя. Комната из хоррора. Кровища, бензопилы... Крипота!
Подвал в гараже он обклеил газетами. Купил на рынке бычьей крови. Заранее на ebay были заказаны какие-то немецкие винтажные бензопилы.
Снималось все на слайдовый Hasselblad.

Но причем тут йойо !?
Заранее из циркулярных пил была собрана йойоха. Понадобилась модель, которая будет ее "крутить". Кожаные перчатки, бинты, кровь.
На итоговой картинке были дорисованы только разлетающиеся капли крови, чтобы передать динамику вращения. Все остальное - фото.


К чему я это все... Найдите себе дело, которое будет вам по душе. Толку от этого будет гораздо больше, чем от работы с 9 до 18...

Оригинальное фото
Сегодня в эфире наброс на regexp’ы аж о двух постах.

Присоединюсь по всем пунктам, разве что за исключением того, что проверять регеспы можно статическими методами (раз, два). Если вы, конечно, не собираете их динамически :) А если собираете,... я даже не знаю как это можно назвать...

У меня как-то была история о регекспах, когда я парсил базу билетного агенства.


В holistic.dev тоже не обошлось без этой черной юниксово-перловой магии :)

Нет, запросы не парсятся регекспами, это невозможно. Для этого используется оригинальный AST-парсер из postgresql.
Выковыривать его оттуда отдельное приключение. Т.к. разработчики не поставляют его как отдельный продукт, они не переживают за обратную совместимость. Поэтому у дерева постоянно появляются и пропадают узлы :)

Регекспы используются для подготовки сорцов, перед скармливанием их в AST-парсер. Т.к. мы маленький стартап и не можем позволить себе написать грамматику, например, под JetBrains Grammar-Kit, приходится выкручиваться.

Т.к. изначально инструмент планировалось интегрировать с IDE, то хотелось сделать так, чтобы при наличии синтаксической ошибке в одной из sql-команд, только эта команда игнорировалась, а остальное парсилось. Именно так все работает в IDE от Jetbrains. Хотелось сделать так же, но нативный парсер такого не умеет - он падает на первой же синтаксической ошибке.

Идея делать плагин для IDE была отложена, а функционал остался. Если в playground сделать несколько ddl-команд, часть из которых будет с синтаксическими ошибками, это не помешает проверке. (выделение ошибочных мест в DDL будет позже, сейчас можно заметить, что поля из таблицы b не попали в экспорт типов).
Часто спрашивают - почему не подсвечивается отсутствующая таблица в запросе? Сейчас мы не ориентируемся на разработчиков, а у DBA не бывает невалидных запросов :) Но справедливости ради, это правило находится в процессе разработки и нашлись corner cases, которые требуют доработки парсера :)

К слову, если у вас есть экспертиза в AST-парсерах, я был бы рад пообщаться (@antonrevyako)
AR, который смог (взято у @honestmarketing)

Согласен с автором на все 100 - в образовании AR самое место. Даже на текущем уровне развития технологий.

PS: Так же автор вспоминает боль от изучения астрономии по плоским учебникам. А я недавно рассказывал о сайте с красивым 3d на тему астрономии - https://news.1rj.ru/str/nosingularity/491