Читаю в последнем номере компьютерных вестей статью про Линтер - российскую СУБД. Честно сказать - веет нафталином. Ну не от самой статьи, а от Линтера. В общем-то вполне понятно, что ничего линтеру не светит - за 10 лет своего существования никакой известности в IT-среде ему достичь не удалось. (Кстати, у американцев есть замечательное слово buzz именно для таких случаев.) Но речь в не о линтере, а о технических решениях, лежащих внутри. Дочитал я до фразы "Данные в таблицах физически хранятся построчно" и сразу внутренне возмутился. Почему это грубейшая ошибка?
пятница, 31 августа 2007 г.
column-oriented vs row-oriented DBs
Рассмотрим подробнее: все знают, что внутри процессора есть кэш-память. И назначение этой памяти тоже все знают. Но почему-то никто не задумывается о том, что память эта мала и относиться к её наполнению нужно бережно. Т.е. если СУБД хранит данные построчно, а запрос выбирает одну колонку, то вместе с данными этой колонки в кэш будут попадать и бесполезные куски данных от соседних колонок. А к чему приводит забивание кэша ерундой? К циклам ожидания процессора - он же вынужден ждать данные. К тормозам.
Представим типичную картину: в таблице с двадцатью колонками лежит миллион записей, выполняется запрос типа "select Field1 from Table1 where Field2 = 22", подходящий индекс оптимизатор определить не сумел и запустил full scan. В процессе выполнения этого запроса будут прочитаны с дисков все страницы данных принадлежащие таблице. Что уже само по себе страшно медленная операция: дисковый ввод-вывод, да ещё и забивающий ненужными данными кэш операционной системы. Потом по каждому блоку будет выполнен поиск нужного поля и его сравнение. В процессе поиска будет просаживаться уже кэш процессора, см. выше. И вот типичный результат: мощнейший компьютер потенциально выполняющий на каждом процессоре 2147483648 (и больше) операций в секунду демонстрирует 100% загрузку и вынуждает разработчика тратить время на профилирование индексов и тюнинг плана SQL-запроса.
А как могло бы быть иначе? А вот как: данные нужно хранить не по строкам, а по столбцам. Т.е. данные каждой колонки - в отдельный линейный массив. Из такой системы хранения получается сразу куча преимуществ - и дисковый ввод-вывод экономится, и кэш операционки, и кэш процессора, да ещё и команды поточной обработки данных можно применять. Да! И индекс по этой колонке становится не нужен - скорость работы позволяет обходиться без него! Красота!
Внимательный разработчик сразу скажет: так что же это творится, ведь везде одно и то же - везде работает первый сценарий! И Oracle записи хранит построчно, и MSSQL, и ещё куча остальных. Да, господа, нас самым наглым образом наобманывают (тоже хорошее слово). Свидетельством тому является два факта: нежизнеспособность систем на распространенных СУБД построенных без индексов и существование систем, которые, образно говоря, "бегают вокруг оракла кругами". Например: Kdb, C-Store, MonetDB. Рекомендую ознакомиться хотябы в общеобразовательных целях.
Ещё более внимательный разработчик скажет: так ведь ноги то растут из использования программистом сложных структур данных: record, union и т.д. И объектов само-собой тоже. Что же, их не использовать? Да. Увы, но получается, что когда у вас реально много данных, то от использования структур придется отказаться.
Вот он, секрет быстрого ПО.
четверг, 2 августа 2007 г.
Markaby vs HAML
Я уже когда-то писал о сравнении двух движков html-разметки для Ruby — Markaby и HAML. Но похоже тот комментарий потерялся, поэтому я повторю у себя в блоге.
Заметка родилась из практической попытки переверстать имеющуюся страницу и в HAML, и в Markaby.
HAML
Плюсы:
- Неплохое визуальное восприятие чистого кода (без конструкций ruby) для генерации html, за счет принудительного форматирования отступами и отсутствия закрывающих тегов;
- Наличие html2haml;
- Отсутствие затруднений с utf-8;
- Язык меняется на "ru" в теге html исходно безо всяких затруднений;
- Xml-пролог удаляется исходно безо всяких затруднений.
- Не валидирует генерируемый html-код!
- Ruby-код включается через расширения синтаксиса - сммволы "-" и "=", что при злоупотреблениях воспринимается как каша;
- Визуальное форматирование выходного кода - оно никому не нужно и увеличивает размер выходного файла;
- Как следствие - проблемы с textarea: закрывающий тег находится на следующей строке с отступом, что приводит к большому числу пробелов внутри контрола. Причем, похоже, что проблема нерешаема в принципе!
- В случае с rails генерируется промежуточный erb. Что затрудняет отладку и отрицательно сказывается на скорости;
- Иногда наблюдается неочевидность синтаксиса (например, закрывающий тег "/") и требуется наличие лишних телодвижений: например, явное указание %meta{'http-equiv' => 'content-type', :content => 'text/html; charset=UTF-8'}/
Базируется на builder.
Плюсы:
- Визуальное восприятие неплохое, причем можно поднять до уровня HAML и лучше, если в шаблоне есть много ruby-кода или если делать закрывающему "end" дополнительный отступ до уровня предыдущего кода
- Валидирует генерируемый html! Это супервещь - сходу нашел ошибку в верстке.
- Ruby-код включается органично по определению.
- Экономит трафик - дает на выходе сжатый html - без отступов и переводов каретки. Но при желании форматирование отступами можно включить. В общем-то это фича builder.
- Отсутсвие html2markaby;
- Базируется на builder и имеет его родовой минус - проблему с раздуванием кода (для кириллицы) из-за оформления символов с кодом больше 127 в конструкцию вида "&##{n};". Это лечится, но некоторые вопросы о корректности фикса мне ещё не ясны.
- Содержит ошибку в закрытии тега textarea. Обходится элементарно, добавлением "do; end", но осадочек остался. textarea :name => 'test[text]', :cols => '50', :rows => '20' do; end О глюке 100% знают разработчики, так что возможно это даже фича.
- Содержит ошибку в URL для DTD. Лечится без проблем.
- Нельзя сменить язык в теге html на "ru". Лечится без проблем.
- Для удаления xml-пролога нужны дополнительные телодвижения. Лечится без проблем.
Кстати, встретил ещё одно интересное мнение в пользу markaby, цитирую:
I like Markaby over HAML because Markaby doesn’t create its own syntax. It’s not whitespace-sensitive; it can be highlighted by your editor already; and because it executes in Rubyspace instead of being parsed (like HAML) it supports all existing Ruby techniques, metaprogramming, and overrides (unlike HAML). This is very valuable to me. Speedwise I would guess they are comparable but I don’t have real data to go by. Unless there is a big speed difference, there is no situation in which I would use HAML over Markaby. That’s partly my personal preference, though.
A big benefit of Markaby is that strings passed as parameters get escaped by default. This means you tend to overescape rather than under, and makes it very easy to write an XSS-secure app.
Подписаться на:
Сообщения (Atom)