[MySQL] Оптимизация дат

Чтобы отправить комментарий — войдите.
  • P
    18 окт 05
    >> Вот тут уже проблема, намного оптимальнее делать выборку по DATE, чем в запросе модифицировать INT`овое поле даты в нужный вид и сравнивать его с нужной датой.

    Во-первых, вообще-то для собственно выборки надо всё сделать с точностью до наоборот — перевести нужную дату в инт и сравнивать в запросе интовое поле даты (проиндексированное, конечно), с интом. Представление дат в любых видах с точностью до дня (типа YYYY-MM-DD) имеет смысл только если где-то нужна группирока по этому полю.

    Во-вторых, сама проблема высосана из пальца. Где именно место собрались экономить? На винте? Полметра? Бу-га-га. В памяти? Полметра? Во-первых, тоже бу-га-га. Во-вторых, в памяти наверняка числа всё равно представит согластно машинному представлению, т.е. по 4 байта. Во-вторых, потеря ресурсов на всякие дополнительные вычисления связанные с такой "оптимизацией" перекроет потерю этих полметра в разы и может превратиться из практически незначительной в заметную. В-последних, если вам надо иметь 500К записей и всех их гонять в каждом запросе без индекса — значит вам на самом деле надо что-то поменять в алгоритмах, а не в представлении данных.
    Ответить
  • R
    24 сен 05
    или сделать три поля с типом enum )
    Ответить
    • Trinux
      Trinux АВТОР
      Roxis 25 сен 05
      ага, и делать выборку по трем полям. Даже если ты сделаешь составной индекс, времени на это уйдет достаточно
      Ответить
  • R
    24 сен 05
    а почему не взять два байта? если нуна сохранить место

    хватит на 176 лет
    Ответить
    • R
      Roxis 25 сен 05
      ну со 176 годами мучаца долга, но 128 без проблем )

      вот типа пример

      число = 5 бит(32 варианта)

      месяц = 4 бита(16 вариантов)

      год = 7 битов (128 вариантов)

      всево 16 бит = 2 байта

      типа решаём сёдня у нас

      $d=25;

      $m=09;

      $y=05;

      $m
      Ответить
      • R
        Roxis 25 сен 05
        нули тока слева убрать, а то октавы получаца
        Ответить
  • sab0tage
    23 сен 05
    Если тебе не нужны секунды, попробуй так. Дата это количество дней от определенного числа, (в дельфях от 1899го года) если тебе нужно датировать ньюсы, то я дкмаю подойдет и от 2000го или 1990го, тогда

    2005.1.10 равно 2005-1990=15(неохото считать весокосные, скажем их было 4)*365+10=5485 такое число может описывать текущую дату. 2байта могут хранить от 0 до 65535, тогда твоя дата займет 2байта. По аналогии поступи со временем. 24*60*60=86400 — 3байта, без секунд 2байта. Тогда при грамотном подходе можно использовать 4байта. Для выборки подсчитай дату и смотри на совпадение.
    Ответить
    • Trinux
      Trinux АВТОР
      sab0tage 23 сен 05
      Тогда при грамотном подходе можно использовать 4байта

      Ну я имею те же 4 байта без гемороя при структуре INT(10). Хотя это и есть то, что ты описал. Это насчет времени. Я тестил эту бню (то что ты предложил, 2 байта без сикунд) — хрен там, погрешность выскакивает. Так хронить время нельзя. А твое предложение по дате — надо подумать, хотя и так видно что выборка уже затруднится (нужны дополнительные вычисления) и так далее.
      Ответить
      • sab0tage
        Trinux 23 сен 05
        Я не понял по поводу погрешности. 24*60=1440, 256*256=65536

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

        515 div 60 = 8 hours

        515 — 8*60 = 35 mins

        тотже трюк с датами. То, что иксы хранят datetime в четырех байтах — неверно! В дэльфях например используется 8byte, float или double, где первые четыре байта — дата, другие 4 время, или дробная часть указывает время. Время в двух байтах можно держать даже точнее чем минуты 65536 div 1440 = 45 — ето значит, что можно держать с точностью чуть ли не до 5ти секунд. А выборка не усложняется, ты же сравниваешь 2 (или 4 если со временем) байта. Просто для каждой даты нужно повторить вычисление.
        Ответить
      • sab0tage
        Trinux 23 сен 05
        по поводу никсового формата 4байта — 4294967296 вариаций

        60*60*24*365=31536000, тогда 4294967296 div 31536000 = 136

        Тогда это хуже y2k, все даты в ихсах ограничены 136 годами :) A DateTime — 8байт, потому, что учитываются мс. Кстати если ограничить

        жизнь ноунэйм 136ю годами, то можно использовать и секунды, но будем верить в лучшее :)
        Ответить
        • Trinux
          Trinux АВТОР
          sab0tage 25 сен 05
          Допустим со временем я тебя понял, но что быть с датой то. В твои 2 байта, она, конечно, взазиет, но стоит ли та экономия байта, расчета текущей даты с учетом весокосных лет при выборки? Надобы потестить
          Ответить
          • sab0tage
            Trinux 25 сен 05
            так давай потестим :) Смотри если брать как год начала остсчета весокосный год, то можно определить так кол-во лет делить на четыре, если без остатка то весокосный — добавляем единицу, тоесть

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

            CurrentDateTime2Int? где инт занимает минимально возможное количество байт, и обратно? С какого года лучше начинать отсчет?

            Насчет резонности экономии байта тебе решать, смотря сколько раз тебе нужно конвертировать дату. Может бытьтак что и нестоит. Хотя твой вариант "дата в формате YYMMDD", предпологает, что чтобы вытянуть ГГ из инт, нужны также мат операции, типа деления и остатка от деления, или перевод в строку, или использование смешанного типа. Можно сравнить необходимое кол-во операций.
            Ответить
            • R
              sab0tage 25 сен 05
              куда то вы не туда, с выкосными годами, непойму где проблема то
              Ответить
              • sab0tage
                Roxis 25 сен 05
                С весокосными годами проблема вот в чем, если брать текущую дату, как количество дней от определенного года, то можно использовать переменную типа инт. Например если за начальный год взять 31.12.2000, то 1.1.2001 можно записать как 1, тогда 1.1.2002 = 2*365+1, и т.д. Так вот, каждый четвертый год не 365, а 366, проблемы большой нет, но и не все так гладко.
                Ответить
            • Trinux
              Trinux АВТОР
              sab0tage 25 сен 05
              Нет, в моем случае все просто, будет запрос вида

              "... WHERE date='".date('ymd')."' ..."

              илиесли посититель переходит по календарю, то брать дату сиз календаря и парсить уже ее. Никаких лишних операций делать не придется. Это во-первых. А во-вторых, если вдруг 99 лет на ННМ не хватит =))) то можно будет легко конвертить дату YYMMDD в другой формат без всяких запар, да и нагляднее она чисто визуально. Хотя все надо тестить
              Ответить
              • R
                Trinux 25 сен 05
                ну или тебе лень кодить, чтоп сделать сложное простым

                или тебе нравица наглядность (а нужна ли она?)

                ни то не другое не приветствую и не вижу тогда проблемы

                так чё за оптимизация нужна?
                Ответить
              • sab0tage
                Trinux 25 сен 05
                Подожди, помимо наглядности, сдесь следующее. Ты дату из стрингового типа переводишь в Дату, которая занимает 4 байта. В принципе я неуверен, что ты получишь большой прирост производительности. Но есть и плюсы в датах как счетчике от числа, например для перехода на день назад/вперед, необходимо просто вычесть/добавить единицу.

                Кстати идея! Слушай, а ведь даты везде хранятся как счетчик от чесла. Переведи дату начала проекта в инт и посмотри на число. Запомни это число — это смещение в днях. Тоесть теперь

                дату начала проекта можно держать как ноль, сегодняшнее число -кол-во дней с момента открытия. Значит выборка и индексация осуществляется по этому маленькому числу (2байта), а для перевода в натуральную дату надо число+число смещение в днях, и результат из инт в дата :) Ну как? Реализация плевая, смещение можно хранить как константу. (Я надеюсь я понятно выразился)
                Ответить
                • Trinux
                  Trinux АВТОР
                  sab0tage 25 сен 05
                  Да, идея хорошая =) а говоришь что не алгоритмизатор =) только опять же стычки с весокосными годами. Да и потом новости не каждый день, поэтому просто плюс/минус еденицей не обойтись, но зато число получается маленькое да и переводить его достаточно просто будет, я думаю. Лишь бы не обжечься на весокосном году. Надо тестить. Переведу какой-нить проект на такую схему, посмотрим
                  Ответить
                  • sab0tage
                    Trinux 25 сен 05
                    с весокосным годом стычки не будет, ты же инт(дата(стринг)) делаешь для перевода, а это автоматом учтет весокосный год.

                    Тоесть можно хранить и инт, но он займет больше памяти так как будет содержать избыточную информацию за количество дней с начала двадцатого века.
                    Ответить
                    • Trinux
                      Trinux АВТОР
                      sab0tage 25 сен 05
                      Да, если функцией прибавлять кол-во дней к точке отсчета проблем не будет. Просто думал как-то проще сделать.
                      Ответить
  • S
    22 сен 05
    Забыть про оптимизацию и использовать XML+XSLT =)))
    Ответить
    • Trinux
      Trinux АВТОР
      sas171 22 сен 05
      Сас ё-маё! Сколько зим! XML+XSLT это связка для мощных серваков, чем мы похвастаться пока не можем. Вот и приходится ебаться =)
      Ответить
full image