Replies (57)

  • @Sectoid, а зачем вам ДВЕ ячейчки?
  • @NokitaKaze, created/updated, например
  • @Sectoid, ты что, четвёртую версию что ли юзаешь?
  • @Sectoid, не знаю кто как, но я пишу это ручками в запросах через UNIX_TIMESTAMP(). Вот прямо сейчас код пишу
  • @NokitaKaze, через код я и вынужден делать. какого дьявола нельзя сделать прямо в базе? обычный же use-case, епта( видимо пора на них обидится и уйти таки на постгрес. давно собирался, да все не хватало "последней капли"
  • @Sectoid, /me безуспешно ковыряется в памяти

    Я точно помню, что вокруг этой хуйни я что-то исправлял. Только никак не могу вспомнить, что именно, и на какой версии. Но в целом вроде же логично — нахуя в таблице больше одной такой колонки?
  • @Sectoid, да, резонно
  • @zamotivator, а чем руководствовались давая такое ограничение? некоторой неоднозначностью?
  • @Sectoid, пожалуй, про это нужно писать отдельный пост. Давно собираюсь.

    Если коротко — отсутствие концептуальной целостности.
    Есть две модели разработки:
    1) делать лишь то, на что есть customer request
    2) если и делать что-то — то делать до конца.

    Вот есть containt'ы. MySQL дальше foreigh keys не ушёл. PostgreSQL сделал их в общем виде,
    Я вот предлагал в Percona сделать cotraint'ы на таблицы и общего вида. Столкнулся с полным непониманием — "а нахуя? ведь и так хватает"
    И так по каждому вопросу.

    Вот конкретно сейчас мир MySQL занимается тем, что убирает лишние IO operations.
    А вот всё остальное, те же window functions ты хуй сделаешь. Почему?

    Потому в MySQL план выполнения запроса — это просто AST с инъекциями. Когда у тебя условия фильтрации валяются в WHERE clause — это ёбанный ад и пиздец. Особенно когда там же лежит additional condition для join. Ты не можешь проводить оптимизации "так просто" — тебе нужно оставлять корректным AST. Что есть полный маразм и идиотизм.

    Поддержать любую новую фичу — ад и содомия.

    И теперь MySQL заложник вот этой модели. Никто не может переписать его, потому что дохуя сайтов уже заточилось на его баги и так далее.

    Другой ШИКАРНЫЙ пример.

    storage engine API сообщает информация про количество уникальных строчек в таблице через rows_per_key — ЦЕЛОЧИСЛЕННЫЙ. Чтобы вычислить количество уникальных ключей — ты просишь общее число записей, и делишь на эту константу. И первое и второе — целочисленное. А количество уникальных ключей в storage engine вычисляется как unique_key_count * rows_per_key

    Т.е. ты теряешь в точности просто из-за челочисленного деления, а потом умножения.

    Но это цветочки. Отдельный пиздец — mysql storage engine не умеет сообщать число null'ов, что сам понимаешь, губительно для join'ов
    В итоге есть глобальная опция myisam_nulls_stats_method и innodb_nulls_status_method. Которая ГЛОБАЛЬНО, для всех таблиц, указывает, игнорировать null'ы или нет. Questions?

    MySQL умрёт. Максимум что может быть — его заменит Drizzle, который переписан, с который можно хоть как-то развивать.
  • @zamotivator, ох, какая стенка) подробно просмотрю позжее, а за drizzle спасибо — взгляну
  • @Sectoid, drizzle ещё мягко говоря не готов к production. Но архитектурно он получше mysql, и в нём есть шанс делать вещи, что в mysql не сделаешь
  • @zamotivator, а у него откуда "ноги ростут"? это масштабно перепиленый mysql или полностью отдельный продукт?
  • @Sectoid, масштабно перепиленный mysql. На бабло rackspacecloud. Потом они бабло перекрыли, и народ оттуда разбежался.
  • @zamotivator, т.е. продукт есть, но ещё сыроватый, и его ещё пилить и пилить. Но его хотя бы можно пилить. MySQL трогать страшно — разваливается от каждого чиха.
  • @zamotivator, MySQL, конечно, когда-нибудь умрёт (и горы не вечны) — но не скоро. И именно по описанным тобой причинам — там что-то такое быстро делают, понятное заказчикам, и на это заточено теперь пол-индустрии. Или, в переводе на русский, потому что он — дешёвое говно. Такое всегда побеждает.
  • @zamotivator, Ну, запросы в MySQL, как я помню по ощущениям книжки High Performance MySQL, вообще нельзя. Потому что каждый storage engine тупо реализует все так, как хочет, а не как надо. Не знаю, как сейчас, но, например, SELECT COUNT(*) на InnoDB выполнял fullscan таблицы вне зависимости ни от чего :) Ну или например в запросе поля, на которых есть индексы, должны были идти первыми в запросе, иначе на них клался болт и выполнялся фуллскан. Ну и такого вот говна — на каждом повороте
  • @zamotivator, понятненько. буду поглядеть. пока что главный кандидат для сбегания — слоник. очень уж радует фичастость. несколько смущает: в нем нет партиционирования (делается через костыли) и вопли народа про кластеризацию. Но поддержку кластера мона сделать и со стороны приложения.
  • @dmitriid, А SELECT COUNT(*) при наличие транзакцый или выполняет fullscan, или имеет отдельную таблицу для каждой из имеющихся, в которой хранит значения для каждой транзакцыи. Учитывая, что второе — это веником убиться, во всех нормальных местах там примерно fullscan.
  • @tzirechnoy, В MyISAM fullscan не выполняется. Не помню, правда, почему
  • @dmitriid, Не знаю, как сейчас, но, например, SELECT COUNT(*) на InnoDB выполнял fullscan таблицы вне зависимости ни от чего :)
    АААААААААААААААААААААААААААА!!!!!!!!!!!!111111111111 вот и последняя капля. где там мой apt-get?
  • @Sectoid, а я чо, я ничо :) не надо на меня ответсвенность сваливать :)
  • @dmitriid, а где я сваливал?) я просто ужаснулся. ну вот и будет чем занятся вечером)
  • @tzirechnoy, ну это же явная ложь. Бегом читай про MVCC, не хранит он отдельных таблиц для каждых из имеющиеся. У тебя на записе в таблице есть скрытый version-id, и каждая транзакция запоминает, какие из них валидны ,а какие уже нет.
    И да, count(*) может считаться на индексе, если чо
  • @dmitriid, Потому, что в MyISAM нет транзакцый, сюрприз.
    (Работающих транзакцый, размеется)
  • @tzirechnoy, Бегом читай про isolation level.
  • @zamotivator, nested-транзакций в mysql нет по этой же причине?)
  • @zamotivator, Бегом читай про MVCC, не хранит он отдельных таблиц для каждых из имеющиеся. Я имел в виду — для быстрого count(*), по-моему из оригинала это вполне понятно.
    И да, count(*) может считаться на индексе, если чоФуллскан индэкса иногда имеет смысл, если чо. От этого он не перестаёт быть типичным фуллсканом.
  • @Sectoid, а это что такое?
  • @tzirechnoy, Пофиг. Все сводится к тому, что поведение MySQL'я весьма недетерминированное (то есть оно почти детерминированное в пределах одного движка — и только). Ах да. Это говно еще вполне способно не суметь залить в себя созданный собой же дамп, потому что "sql error: invalid expression" :)
  • @tzirechnoy,

    Я имел в виду — для быстрого count(*), по-моему из оригинала это вполне понятно.
    Не хранит.

    Фуллскан индэкса иногда имеет смысл, если чо. От этого он не перестаёт быть типичным фуллсканом.
    Естественно, перестаёт. В разы так
  • @dmitriid, оно вполне так себе детерминированное. Просто зачастую, чтобы его понять, нужно почитать сорцы.
  • @zamotivator, Бегом читай про isolation level.От того, что я ещё про него что-нибудь прочту, в MyISAM появятся транзакцыи? Или можно будет сделать count(*) без fullscan?
  • @Sectoid, нет, поддержать такую штуку в текущем коде — ИМХО полный unreal
  • @tzirechnoy, в MyISAM транзакции есть. Просто Isolation Level неудовлетворительный для тебя. Это разные вещи
  • @zamotivator, а чуть подробнее можно?
  • @zamotivator, и какой из них в MyISAM и в InnoDB?
  • @zamotivator, Не хранит.(Саркастически) я заметил. О чём тожэ написал в оригинальном комменте.
    Естественно, перестаёт. В разы такС фига ли теперь full index scan, который выбирает по записи на каждый тупл примерно, перестаёт быть fullscanом? Только от того, что он быстрее (но не на степенной порядок) фуллскана на основное тело таблицы при некоторых данных? Теперь любая оптимизацыя фуллскана превратит его в нефуллскан что-ли?
  • @zamotivator, И какой он там? dirty read? Нет, товарищ, это слово как раз значит, что транзакцый там нет.
  • @tzirechnoy, С фига ли теперь full index scan, который выбирает по записи на каждый тупл примерно, перестаёт быть fullscanом?
    Например, ему не нужно хотить на последнюю страницу B-Tree дерева. А это уже на порядок меньше операций.
    Или вы знаете какие-то другие волшебные операции, что позволяет count(*) делать за отличное от O(n) время?
  • @Sectoid, MyISAM — READ UNCOMMITED, InnoDB — Repeatable Read
  • @zamotivator, Например, ему не нужно хотить на последнюю страницу B-Tree дерева. А это уже на порядок меньше операций. С фигалли? в последней страницэ вроде всего лишь хранятся данные с самым большым (по order) значением ключа.
    Или вы знаете какие-то другие волшебные операции, что позволяет count(*) делать за отличное от O(n) время?Представляю, но они мне не нравятся. О чём я, опять жэ, написал в первом комменте.
    Ктати, хорошо было бы индэксы стабильных двусторонне-детерменированных групповых операцый добавить (не знаю, можэт у кого ужэ и есть, на самом деле, давно не слежу за новинками ни в каком из четырёх SQL-серверов, с которыми работал).
  • @zamotivator, ясн. интересно какой у слоника...
  • @tzirechnoy, 1) ты путаешь B-Tree и B+-Tree деревья.
    2) GiST позволяет такое сделать
  • @Sectoid, офигеть. слоник умеет все 4 )) postgresql.org
  • @zamotivator, 1) С чего это я их путаю? Тем более, что там отличие по-моему только в алгоритме балансировки, который нам при чтении вообще не важэн.
    2) Видимо, да, впрочем как и правильный конфиг gcc.
  • @Sectoid, Как раз dirty read он и не умеет. :-)
  • @tzirechnoy, Хм? READ UNCOMMITTED в postgresql.org — не оно разве? О_о
  • @Sectoid, In PostgreSQL READ UNCOMMITTED is treated as READ COMMITTED, while REPEATABLE READ is treated as SERIALIZABLE.

    все, понял, я йолоп)
  • @tzirechnoy, В B-Tree дереве вполне возможно хранить counter'ы про количество записей на каждой странице. В B+-Tree дереве это невозможно
  • @Sectoid, чтот у меня что ни пост, то холивар)
  • @zamotivator, Чем они по-твоему отличаются вообще?
    По моему мнению, B-tree — это balanced tree (изредка binary tree), а B+-Tree — это balanced tree с алгоритмом обновления BTRee+.
    counterы для версионника и там и там хранить нетривиально, поскольку counter должэн содержать информацыю о видимых версиях (развесистая достаточно структурка) — и это перестаёт быть просто B+-Tree.
    А блокировочники ужэ передохли все, туда им, впрочем, и дорога.
  • @tzirechnoy, И что такое в твоём понимании "алгоритм обновления B+-Tree"?

    B+-Tree отличается от B-Tree тем, хранятся в промежуточным страницах копии значений из source, или уникальные значения
  • @zamotivator, Любопытная трактовка. Впервые такую слышу.
    Впрочем, в таком случае я никогда не видел вжывую B-Tree.
    И да, можэшь начать объяснять, как это в full index scan B+-Tree ты собираешься пропускать какую-то страницу (я так и не понял, конечно, какую).

    Алгоритм обновления BTree+ — это примрено то, что описано в википедии в статье B+-Tree в параграфах Insertion/Deletion. Никогда их не реализовывал, потому более детально вряд ли со мной его имеет смысл обсуждать.