1. PHP / Говнокод #13205

    +164

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    $res = mysql_query('select `date` from `pic`');
    
    while($data = mysql_fetch_row($res)){
           if(date('d.m.y') != date('d.m.y',$data[0])) continue;
           $countPicToday++;
    }

    Не понятно. Почему нельзя было использовать COUNT() и WHERE

    Запостил: AlexP, 20 Июня 2013

    Комментарии (32) RSS

    • PHP LINQ
      Ответить
    • Потому что лучше писать код на чистом πхπ (tm)
      Временный код, пока автор не напишет свою субд на πхπ
      Ответить
    • Не все так умеют, это слишком тайное знание.
      Ответить
    • и эти же люди пишут апострофы вместо кавычек, "чтоб быстрее было"
      Ответить
    • Потому что в InnoDB COUNT() при наличии WHERE тормозит. А нет, наоборот же, COUNT() без WHERE тормозит. Ну тогда не знаю...
      Ответить
      • В MyISAM же... В InnoDB большой разницы не должно быть, как и в любых других многоюзерских базах.
        Ответить
        • В MyISAM полное количество строк в таблице указано в её заголовке, поэтому COUNT() без WHERE отрабатывает мгновенно, используя магию.

          В InnoDB же нет никакой разницы, есть WHERE или нет, потому что в любом случае строки придётся пересчитывать.

          Это и послужило почвой для «жёлтых» статей с заголовками типа «В InnoDB COUNT() тормозит!!!11адын-адын-адын».
          Ответить
          • Ну так я про это и пишу ;) Что тормозит COUNT() с WHERE именно в MyISAM, а в InnoDB он тормозит всгеда ;)
            Ответить
    • Пара гипотез:
      • потому что в MySQL функция DATE_FORMAT() и сравнение строк тормозят;
      • в PHP был вызов date_default_timezone_set, поэтому DATE_FORMAT() и date() возвращают разные результаты.
      Ответить
      • Могу сказать что сайт работает по серверному времени. А весь код полон таких шедевров (например чтобы узнать ИД вставленной записи автор делал еще один запрос, и не важно что после этого могли быть добавлены еще строки). Так что просматривая это все я не углядел какого то преимущества у этого метода.
        Ответить
      • Кому-то было впадлу расчитывать диапазон:
        WHERE date >= mktime(0,0,0) AND date < mktime(0,0,0) + 86400
        Ответить
        • Во-первых, два условия не нужно, потому что есть BETWEEN.
          Во-вторых, mktime не нужно, потому что сравниваются две готовые даты.
          В-третьих, в SQL есть и функция DATE(), округляющая до целой даты, и выражение "+1 day", так что высчитывать количество секунд в сутках не нужно.
          Ответить
          • 1. Вы помните входят ли значения BETWEEN в диапазон или только ограничивают? Я — нет.
            2. Не понял, что значит "две готовые даты". Судя по запросу date имеет тип int.
            3. DATE "огругляет", да. Прощайте индексы.
            Ответить
            • > Вы помните входят ли значения BETWEEN в диапазон или только ограничивают?
              Тру ПХП-вей: вместо того, чтобы заглянуть в документацию, написать самому.
              Ответить
              • Его ник как бы намекает нам...
                Ответить
              • Явное лучше неявного. Вы наверное и в условиях скобки тоже не расставляете, т.к все приоритеты операций помните?
                Ответить
                • Собственно, between - специальная конструкция придуманная для того, чтобы возникало меньше проблем связанных с необходимостью писать скобки, т.как превращает два условия в одно.
                  Ну а вообще, я сторонник языков, где скобки однозначно влияют на смысл :) и в произвольном порядке их не расставить.
                  Ответить
            • 1. This is equivalent to the expression (min <= expr AND expr <= max) if all the arguments are of the same type. Следовательно, из суток придётся вычитать секунду, чтобы второе неравенство стало строгим.

              2. Виноват, не подумал о том, что mktime с опущенными аргументами как раз возвращает текущую дату, округлённую до нужного состояния. В Вашем выражении надо уточнить, что mktime — функция PHP, а не SQL.

              3. А мы будем округлять не поле date, а текущее время. Тогда с индексами будет всё нормально.

              Итого:
              'WHERE `date` BETWEEN ' . strval(mktime(0,0,0)) . ' AND ' . strval(mktime(23,59,59))


              Или, если MySQL и PHP работают по одному времени, то
              WHERE `date` BETWEEN UNIX_TIMESTAMP(CURDATE()) AND UNIX_TIMESTAMP(CURDATE() + INTERVAL 1 DAY - INTERVAL 1 SECOND)
              Ответить

    Добавить комментарий