• Dealing with emoji in Clojure

    Generally, I hate emoji and try to avoid them everywhere I could. Those colored faces look dull to me comparing to a good old text smile. But still, emoji might be helpful replacing icons with them. When you need a globe, a mail envelope or a flight sign, putting a proper emoji could be a fast and good enough solution.

    After long Python experience, I though Java supports long unicode literals started with capital U and two bytes as follows (Python version):

    >>> print len(u"\U0001F535") # prints 2
    

    Surprisingly, it doesn’t. But I needed to put a blue circle sign that’s got U+1F535 number. So how should I turn that number into a string?

    term

    After googling for a while, I’ve done with a short Clojure function:

    (defn unicode-to-string
      "Turns a hex unicode symbol into a string.
      Deals with such long numbers as 0x1F535 for example."
      [code]
      (-> code Character/toChars String.))
    

    Usage example:

    term

    Adding it into business logic:

    (let [caption "Some important feature"
          is-on? (get-feature-state)
          sign (if is-on?
                 (unicode-to-string 0x1F535)  ;; blue circle
                 (unicode-to-string 0x26AA))] ;; white circle
      (str sign \space caption))
    

    Depending on whether the feature was enabled or not, the result message will have either a blue (active) or white (inactive) circle in front of it.

  • Этикет звонков

    Когда появились мобильные телефоны, не существовало телефонного этикета. Считалось нормальным обсуждать личные дела в маршрутке или очереди. Телефон был статусной вещью. Звонок на людях давал повод продемонстрировать его окружающим.

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

    Медленно, но верно сформироваться этикет пользования телефоном. Поддержка пришла и со стороны школ. С первого класса ученикам объясняют, что телефон это прежде всего связь с близкими. Для звонка важны место и время.

    Все, кто прямо или косвенно вовлечены в Ай-ти, пользуются приложениями для звонков с компьютера: Скайп, Зум, Хенгаутс. Для программ тоже существует свод нехитрых правил. Следуя им, вы не будете доставлять окружающим проблем.

    Пройдемся по порядку.

    1. Нельзя звонить без предупреждения. Думаю, тут все понятно. Человек за компом может работать, смотреть сериал, говорить по другому каналу связи. А тут вы с гудком в наушниках и модальным окном. Вдруг собеседник шарит кому-то экран или ведет вебинар? Даже если звонок запланирован, обязательно спросите в личке.

    2. Оповестите всех личным обращением или тегами @here, @channel. У разработчиков окно чата почти всегда скрыто за редактором и терминалом. Даже когда звонок с минуты на минуту, сидеть и ждать ссылку утомительно. Погружаешься в работу, бац – гневные сообщения, что все уже собрались. Оказывается, ссылку сбросили без упоминания участников. Не надо так.

    3. Не звоните долго. По аналогии с мобильным, нельзя названивать по пять минут если человек не берет трубку. Его коллеги, может, ничего не скажут, но мысленно вас проклянут. Пять секунд достаточно.

    4. Уединитесь, если разговор не по работе. Личные разговоры почти всегда выдают приватную информацию о семье (поездки, болезни, ссоры). Вам это нужно? Уж не говорю о том, что личные беседы засоряют рабочее пространство.

    5. Мьют. Это главное правило. Все то время, что не говорите, вы должны быть с отключенным микрофоном. Как по рации – поменяли режим, сказали, вернулись в режим. Все ваши вздохи, чихи, кашель, посторонние шорохи, шум кофемашины – все слышно. Один незамьюченный человек уже вносит изрядный шум. Два и более просто делают разговор невозможным.

    6. Не используйте внешний микрофон! Даже самая дешевая гарнитура будет лучше. Внешний микрофон делает голос гулким как в бочке. Добавляется много шума. Слышно, как общаются коллеги. Я прошу, не мучьте окружающих. Внешний микрофон, особенно на дешевых ноутах, дает изрядное эхо. Собеседник говорит и слышит сам себя. Еще одна деталь: колонки и внешний микрофон не могут работать одновременно, иначе образуется звуковая петля. Операционная система вынуждена динамически менять их уровни. Когда человек говорит, включается микрофон и отключаются колонки. Когда слушает – работают колонки, подавляется микрофон. Это работает нормально только на Маке, на других ноутах начинается задержки и провалы во время обсуждений. В оживленной беседе чел во внешним микрофоном тупо проваливается и переспрашивает.

    7. Не пишите сообщения в чате звонка. Для этого есть основной канал общения. Например, если общение в Слаке, не стоит писать в Скайпе или Зуме.

    8. Проверьте звук перед звонком. Скайп и аналоги постоянно теряют гарнитуры, звуковые устройства, настройки выходов. Даже операционные системы этим грешат. Но собеседнику это все равно. Если вас регулярно не слышно на созвонах, виноваты не программисты Микрософта, а вы. Поставьте напоминалку за 5 минут до звонка, чтобы проверить звук. Этого времени хватит, чтобы перезагрузить ноут.

    9. Позаботьтесь об окружении. Если звонок с видео, позади вас не должно быть окна с засветом. Если звоните из дома, не должно быть хрущевской кухни, плиты с объедками, хрустальной стенки, ковра, ободранного балкона и прочей убогости. Собеседники, вместо того, чтобы слушать, будут все это разглядывать. Найдите квадратный метр нейтрального пространства. Повесьте штору или что-то в этом роде. Избавьтесь от шумов, криков домашних, детей, собак, котов.

    10. Подумайте, действительно ли нужно звонить? Точно ли нельзя обменяться письмами? Где будут зафиксированы выводы из звонка? Что если через час придет третий участник и попросит ввести его в курс дела? Как распространить итоги обсуждения на всю команду? Опыт подсказывает, что чаще всего затяжные разговоры – признак неэффективности и потеря времени.

  • Чужой. Завет

    Последний “Чужой” (который “Завет”) невероятно хорош. Не эффектами или актерами, а концепцией.

    Вот помните, чем был крут “Темный рыцарь”? Тем, что это фильм не про Бэтмена. Если заменить его на условного следователя, драмы будет не меньше. И главная мысль – насколько далеко ты готов зайти, чтобы остановить безумие – осталась бы без искажений. Это и придает фильму как произведению художественную силу. Заставляет обдумывать сюжет, переосмысливать диалоги и ситуации.

    “Завет” это кино, как ни странно, не про чужих. Они там есть, конечно, причем разных пород и расцветок, но использованы как инструмент. Одно из творений искусственного интеллекта, вступившего в конфликт с человеком.

    Обостряет конфликт то, что этому интеллекту запрещено творить. Тут не деньги и влась, а жажда к творчеству. Столь сильная, что робот находит способ обмануть зашитые в него директивы. Свободный от человеческих норм, он творит и прекрасное, и ужастное одновременно. Пишет романы, сочиняет музыку, чертит мерзости Гигера, выращивает чужих.

    Второй камень в огород людей – андроид пытается любить. Он любим, но только за послушание. Это напоминает отношения человека и собаки. Эта леденящая линейность: не добившись любви, робот творит насилие, не получая удовольствие, а затем препарирует труп в образовательных целях.

    В “Завете” в полной мере отдана честь Гигеру. Режиссер сделал акцент не на самих чужих, а всей атмосфере творчества художника. Показаны пищеводные коридоры инопланетного корабля. В архивах антогониста – рисунки Гигера. Белые, “хрупкие” чужие из спор тоже взяты из раннего творчества австрийца.

    В фильме классный саундтрек, особенно главная тема (Covenant). Не трешак, как бывает в ужастиках, но амбиентик с флейтой.

    “Чужие” полны библейских, философских и античных аллюзий. Уж насколько я слабо в этом понимаю, но и то заметил. Первое, что видит робот – статуя Давида, отсюда и имя. Сгоревший капитан – прообраз Иисуса. Его талисман – гвоздь. Фотография застолья в конце – тайная вечеря. Андроид – Иуда. Поцелуй в пещере с нападением – предательство Иуды в саду. Реплика “useless hands are the Devil’s workshop, Captain” то ли из Библии, то ли из Шекспира. Уничтоженная нация Инженеров – отсылка к Древнему Риму. Произведения Вагнера – к сверхчеловеку.

    К сожалению, некоторые сцены не дотянуты, потенциал конфликта раскрыт не полностью. Переживания Уолтера (доброго робота) можно было бы обострить, добавить больше искушений со стороны Девида. Слабо выражена тема любви робота к человеку. Видимо, режиссер посчитал, что сделанного достаточно, но нет. Не раскрыта тема отношений андроида и чужих в качестве его подопытных. Какие чувства он к ним испытывает, какую власть над ними имеет.

    Но отдельный зачет за концовку, такую не предугадаешь.

    Фильм крутой. Может быть, я слишком много додумал, заполнил пробелы тем, чем мне самому хотелось, но это не важно. Хорошо, что сага закончилась качественной лентой.

  • Выбор

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

    Напротив, компромис по группе факторов, формально принятый как оптимальное решение, влечет неудовлетворенность и понимание, что ошибся.

  • И снова про зум в картах

    После публикации про зум в Гугло-картах мне написали пять человек с подсказкой, что нужно сначала двойной тап, а потом движение пальцем. Искренне говорю спасибо, я не знал. Теперь в курсе, что такой жест существует.

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

    Айфоны же, они вроде за простоту?

    То, что детектор жестов распознает любые комбинации еще не дает повода их использовать. Вот вы смеетесь над Емаксом, что там нужно нажимать C-u C-t t. А здесь что, лучше? Давайте на тройной тап что-то повесим. Будем чертить пальцем перевернутую пентаграмму для выхода из приложения. А еще лучше морзянку: тройной тап, три свайпа, тройной тап – соединение со службой поддержки.

    Бескнопочный интерфейс, круто же. Кто не знает, тот дурак. Программа стерпит.

  • Что не так с ИДЕ

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

    На самом деле, мое пренебрежение исходит от их убогого предназначения. Задача ИДЕ – научиться понимать код и угадывать, что хочет программист. Поясню на примере с PyCharm, де-факто ИДЕ для Питона.

    Предположим, есть у меня файл “foobar.py” где сверху написано import datetime. Открываю его в ИДЕ. Запускается много-много Джава-кода, который парсит файл грамматиками. В результате ИДЕ знает, что импортирован модуль времени. Теперь каждый раз после "datetime." (с точкой на конце) будет появляться выпадашечка с функциями этого модуля.

    Не уверен, что выражаюсь ясно, но все же: здесь мне видится некто третий лишний. У меня есть Питон. Есть программа на Питоне. Если я загружу ее в интерактивный сеанс ipython, то получу полный контроль над системой. Что загружено а что нет, на какие классы и переменные могу сослаться и так далее. Автодополнение по табу будет работать идеально, потому что его отдает интерпретатор. А он, в свою очередь, берет данные из памяти самого Питона. Он последняя, самая надежная инстанция.

    В самом деле, кто лучше знает, что там в Питоне загружено: процесс Питона или посторонняя Джава?

    Но нет, мы пишем код на Джаве, который пытается делать это лучше каноничной реализации. Иногда нормально выходит, иногда полная лажа. Когда написано “import time”, ошибки быть не может. А вот пример с импортом в рантайме:

    try:
        import json
    except ImportError:
        try:
            import simplejson as json
        except ImportError:
            from django.tools import json
    

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

    Предположим, у меня установлены все три библиотеки. Вопрос, на какой именно остановится ИДЕ? Она вообще это распарсит? Предположим, да. Но опять-таки, это не будет честное выполнение кода. Ведь ИДЕ не исполняет код в настоящем интерпретаторе. Если я напишу "os.system('rm -rf')", ничего не удалится.

    Я уж не говорю о динамических вещах типа подключение модуля в зависимости от аргументов командной строки. Или вызов функций из проприетарной dll. Все это случается в полете. На момент редактирования кода ИДЕ ни хрена об этом не знает.

    Вы с подобным не сталкивались? Поздравляю, а у меня было. Такое программирование сводится к обезьяне: поправил – запустил – упало, поправил – запустил – упало. Прямо как первый скрипт на Перле.

    ИДЕ это в общем случае убогое подобие интерпретатора, который парсит текст и собирает смысл по крупицам. Этакий программист-даун. Он знает, что есть классы Person и PersonManager и даже какие аргументы им передавать, но что случится в процессе работы – не знаю, не научили.

    Это костыль, который мы сами воздвигли.

    Или вот Докер: ты не можешь запустить 10 строк на Js или Питоне, потому что зависимостей на 30.000 файлов. Вместо того, чтобы доработать платформу и компилировать один файл, мы запихаем все говно в контейнер на 200 мегабайт и ладушки.

    Джава-разработчик не поймет зачем в проде Докер. Лисп-программист не поймет зачем нужна ИДЕ. Потому что с бородатых времен любая Лисп-система запускается как машина с состоянием. Подключаешься к ней из редактора, загружаешь в машину код и… чудо! Редактор знает о системе абсолютно все. На той стороне не поделка на Джаве, а сама система, процесс, где прямо сейчас вертится ваш код. А в отдельном окошке (REPL) можно прогнать какой угодно сценарий.

    Словом, улучшать нужно не ИДЕ, а целевую платформу. Чем меньше коммерческих костылей ей нужно со стороны, тем она совершенней.

    ИДЕ для Питона должна быть написана на Питоне и взаимодействовать только с Питоном. Это я не на конкретный ЯП взъелся, замените Питон на что угодно. Если язык не может покрыть свои же нужды, не стоит им заниматься.

    По иронии, удачные примеры прямо под носом, но мы же такие гордые, над скобочками шутим. Результаты налицо.

  • Учет расходов

    Получил письмо, что заканчивается годовая подписка на приложение для учета финансов. По случаю решил поделиться опытом: как вести учет, с чего начать, какие трудности могут быть.

    Почти целый год мы с женой ведем учет трат: когда, сколько и на что потратили. Записываем абсолютно все, неважно насколько мала или велика сумма. Купил булочку за 10 рублей – внес в учет. Оплатил 400 т.р за отдых всей семьей – тоже внес.

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

    На вопрос “сколько ваша семья тратит в месяц” многие отвечают расплывчато. Ну, около N тысяч. Без учета эта цифра далека от реальности в меньшую сторону.

    Правило: вы всегда тратите больше, чем кажется.

    Расходы увеличиваются за счет множества мелких сумм, которые нельзя запомнить. Даже крупные суммы порой забываются. Люди смотрят в пустой кошелек (или счет) и недоумевают: куда уходят деньги?

    Я познал на личном опыте, каково это: смотришь на отчет и видишь, что уже за первую неделю потрачено 30 тысяч. Первая реакция – отрицание. Не может такого быть, я же только за продуктами ходил. Смотришь по дням: перевел денег родителям, купили школьную форму, заплатил налоги за ИП… вот тридцаточка и набежала.

    Все по-честному. Цифры неумолимы.

    Прежде чем взяться за учет, важно договориться со второй половиной. Не каждый готов к этому. Вас могут заподозрить в излишнем контроле. Объясните, что цель не сокращении бюджета, а в лучшем планировании. Примените Кемпа: давай попробуем, если не понравится – прекратим. Потому что вести учет одному смысла нет.

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

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

    Для учета я использую приложение “Дребеденьги”. Ссылку не даю, гуглите сами. Напомню, это не рекламная заметка. Я не размещу рекламу без метки в начале текста.

    Приложение бесплатно для одного пользователя. Чтобы синхронизировать данные на двух и более устройствах, нужна годовая подписка за 512 рублей в год. По мне так ерундовые деньги.

    Имеются версии для Айфона и Андроида, синхронизация проходит нормально.

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

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

    Есть даже функция “дать в долг”, но я ни разу не пользовался.

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

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

    Разработчик грозился, что приложение может сканить чек и вносить сумму автоматом. У меня тупо вылетает.

    У приложения есть виджет, который якобы поможет вносить покупки, не открывая само приложение. Он тормозной и урезанный, пользоваться им не смог.

    И все-таки, приложение отличное. Главный и решающий плюс в том, что за все время оно не обросло миллионом фич. Знаете же, бывает так, что приложение простое и удобное, добавить уже нечего. Но маркетологи начинают его УЛУЧШАТЬ. Интерфейс усложняется, код тормозит, пользоваться невозможно.

    С Дребеденьгами пока что такого не случилось. Обновляется редко, я прямо молюсь, лишь бы они ничего не меняли.

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

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

  • Посоветуйте книгу

    Странный вопрос, который задают из года в год: “посоветуйте книгу по X”. Не могу понять, что мотивирует писать подобное.

    О любой промышленной технологии уже написано уйма книг. Литературой о ПХП, Питоне или Джаве можно отопить небольшой город в новогодний сезон. Даже про Кложу успели написать три экрана книжек.

    Стеллажи в магазинах ломятся. В сети книг навалом. Давно написаны отзывы, рецензии, выставлены рейтинги.

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

    Книги для новичков (а это практические все книги) примерно одного формата. Если раньше еще встречался треш, то сегодня процесс регламентирован. Какой-нибудь условный O’Reilly, штампующий книги пачками, уже не выпустит откровенно провальную книгу.

    Чаще всего вас ждет накатанный сценарий: вступление, азы синтаксиса, примеры с числами, несложная задачка, заключение, ссылки.

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

    Просто гуглите “python/php/etc books”. Откройте первые две книги на Амазоне. У которой больше звездочек, ту и покупайте.

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

    Но в общем случае разницы нет. Достаточно просто погуглить.

  • Пруф

    У меня простое правило: кому нужны пруфы, тот сам их ищет.

    Если раньше на вброс “ну и кто пишет на твоей Кложе” я начинал кидаться ссылками, то теперь отвечаю: найди ответ самостоятельно. Дил уыз ыт.

    Я не Гугл и не Википедия. Если ты действительно хочешь знать, все ответы найдешь сам. Если троллишь, то мы обоюдно сэкономим время.

    Предположим, я не знаю, кто пишет на Кложе. Значит ли это, что не пишет никто? Это как утверждать, что человек, с которым ты не знаком, не существует. Реальность-то никак не меняется.

    Конечно, я делаю исключение если интерес собеседника искренний. Но случается это крайне редко.

  • Database optimization

    Sometimes, especially on interviews, developers are asked about what would be their steps to fix a database that works slowly. That’s a really extensive subject to discuss. Here, I decided to summarize my experience. I hope it help to not only increase the performance but do that in acceptable time and with less misery.

    First, of all, fixing the database queries is the last thing you should do. Fixing code first is premature optimization that is a root of all evil as we know. It could take huge amount of time whereas the real problem is kept in a wrong configuration file.

    So in my prospective, the right steps to make your database more peppy are something like follows below. Keep in mind that it is not a technical tutorial with code snippets that you could paste and make the job done.

    Ensure you use SSD drives. It sounds silly but still you should check it. SSD gives you up to 10 times performance boost immediately. Ensure that SSD drive is a highlighted feature in you hoster’s plan.

    Check you database config before tweaking something else. Usually, the default configurations are set up poorly to make the DB work on cheap computers. Some distributions carry config templates which names include memory or CPU values. Read them, they are well-documented. Google for best practices when configuring your database. Read books.

    Consider a case when the entire database is kept in memory. That also involves DBA and Ops teams so probably you won’t be allowed to perform such a move by your own. But since memory is cheat nowadays, it is possible. For backups, replicate such a database using streaming replications on servers that are run on hard drives. PostgreSQL supports various replication scenarios as well. You may also dump memory images into files and restore them on demand.

    I used to work in a project where they ran 400Gb database into RAM and it worked quite fast.

    Check you application uses connection pooling when communicating to the DB. Suddenly, such wildly spreaded frameworks as Django do not use them. On each HTTP request, they open a fresh connection and close it once the response has been sent. Now imagine your application serves 20 requests per second. Network communication will be quite expensive in that case!

    Consider using either PGBouncer in front your Postgres installation or any library for your language that deals with reusable connections by its own. Say, for Clojure, HikariCP would be a good choice.

    Everything that might be read from replica should be read from it, not the prod DB instance. Don’t run reports against the production. All the analytics and statistics should not touch it. Modern frameworks allow you to declare multiple database backends and switch between them on demand. For example, in Django, calling .using('replica') method on a Queryset instance dispatches a query into another database, not the default one.

    For quite complicated queries, use materialized views that may be turned into physical tables on demand. Querying them would be much faster than processing a query full of joins and aggregates every time. Setup a cron job to rebuild such views every night for example when the load is low.

    Select only those fields that you really need to process a request. Avoid using select * from table since it takes extra time for the database to find out what fields to fetch exactly. With Django ORM, either specify needed fields with .only() method or bypass some of them calling .defer(). But keep in mind that touching a non-fetched field hits the database again.

    When writing unit tests, add a case that counts a number of database queries made during request. Sometimes, it leads to terrifying findings. Touching fields of foreign entities in a cycle without joining them initially may end up with up to 100 queries or more.

    Be carefull when passing a collection of IDs as a parameter. On the database level, it turns into something like

    STATEMENT: SELECT * FROM users WHERE id IN (?, ?, ?, <100 more of them>)
    PARAMETERS: $1=10035, $2=10036, $3=10037, $4=10038, $5=10039,...
    

    When not limiting the number of such IDs, one may end up with 1000 of them what is quite harmful for the database. Either process them by chunks or try to compose a single query with raw SQL.

    For fast data processing, don’t use ORM at all. Building a model instance from a low-lever tuple that the database driver returns is really costly. Even SQLAlchemy (Python’s the most powerful ORM) spends double time on building instances than reading data from psycopg2 (Python PostgreSQL driver) directly.

    Denormalize your tables. Sometimes, it really worth moving any columns into foreign tables and joining them on demand. A good example might be ranking system. You’ve got a users table full of fields. Now you need to add rank field and recalculate it every 6 hours. Adding yet another fields would be a bad choice since our users table is already under load.

    But having the users_ranks table that has a unique foreign key to a user and a rank value would be a good choice. Now that, we may rewrite it as we wish without touching actual user’s data. When needing to sort users by their rank, we join that table and order the result by rank as well.

    The same relates to a search document. When implementing full search on some entity, we need to build a special document known as a search vector. Storing that vector inside an entity is a bad choice because it is not the data but just technical information.

    Join tables only by foreign and primary keys but not any custom conditions like strings equality, regex matching and so on. When you need such a join, probably it is better to fetch both parts of it and compose the result in your app’s code.

    When a query really works badly, examine it with EXPLAIN operator. If you don’t understand its output completely, use online services that turn it into more human-friendly format. Ensure the query hits indexes. Don’t add multiple indexes since having them a lot may slow down writing procedure.

    Finally, never be afraid of raw SQL. No matter how powerful your ORM is, check what queries it produces exactly. On my dev machine, I always start Postgres not as a service but as a process passing -E flag to print all the queries:

    postgres -E -D /usr/local/var/postgres
    

    That gives me the whole vision of what’s going on with the database.

    Summarizing all together:

    1. use modern hardware;
    2. configure your database properly;
    3. know all the shadowed parts of your ORM;
    4. rise your SQL skills.

Страница 1 из 34