1. SQL / Говнокод #8909

    −108

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    update People
             set PeopleIsJunior='N'
           where PeopleIsJunior='Y'
             and month(BirthDay)=(select month(getdate()))
             and year(BirthDay)=(select year(getdate())-18) 
             and day(BirthDay)=(select day(getdate()))

    Еженочно часа 3 делаем людей совершеннолетними. людей много , миллионы, и с табличкой активно работают.
    Наличие индекса по BirthDay не играет никакого рояля, т.к. функции.
    t-sql если чо.

    Запостил: bliznezz, 06 Января 2012

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

    • А BirthDay - это поле какого типа?
      Ответить
    • Пару бредовых идей по оптимизации:
      1. Добавляем дополнительное поле в таблицу MatureDate типа datetime, в которое уже при вставке записи в таблицу будет рассчитываться когда человеку исполнится 18 лет. Условие where будет выглядеть:
      where PeopleIsJunior='Y' and MatureDate = getdate()
      минусы - избыточность данных
      2. Сравнивать разницу в днях и приблизительно считать, что кол-во дней до совершеннолетия 6574.
      where PeopleIsJunior='Y' and cast(getdate()-BirthDay as int) = 6574
      минусы - небольшая погрешность для тех, у кого високосных годов до совершеннолетия было не 4 :)
      Ответить
      • Что-то с первым методом натупил, можно ж:

        DECLARE @MatureBirthDate DATETIME
        SET @MatureBirthDate = dateadd(yy,-18,getdate())

        update People set PeopleIsJunior='N'
        where PeopleIsJunior='Y' and BirthDay < @MatureBirthDate
        Ответить
        • Ну с учетом что не только дата но и время, то там надо вычислить начало дня и конец дня, который был 18 лет назад.
          where BirthDay between @begin_datetime and @end_datetime
          Тогда индексы и статистика раскрываются в полной мере.

          ну или
          where PeopleIsJunior='Y' and BirthDay < @end_datetime
          шикарно и точнее сработает, подчистит если где-то что-то когда-то не отработало, но дорого. т.к. в этом случае придется прочитать слишком много строк данных, где вообще-то и так PeopleIsJunior='N'
          Ответить
          • Предыдущие 2 комента мои.
            На сколько я вижу, то в каждый момент выполнения скрипта нам нужно проставить признак совершеннолетия для людей соответствующих условиям:
            1. Признак совершеннолетия не проставлен ранее;
            2. 18 лет стукнуло человеку в промежуток времени от начала запуска предыдущего скрипта до начала запуска текущего скрипта.
            Эти требования вполне покрываются условием:

            where PeopleIsJunior='Y' and BirthDay <= @MatureBirthDate,

            Кстати, на 99% уверен, что в базе вы храните в поле BirthDay только дату, а время там 00:00, что означает, что под условием подпадут все люди, у которых именно в этот день ДР и делать дополнительные хаки с добавлением времени 23:59 вовсе необязательно.
            Далее.
            Вешаются два индекса: первый на PeopleIsJunior (я бы перегнал его в тип bit, если кроме "Y"/"N" там ничего не хранится); второй на BirthDay.
            Стоимость вставки данных в таблицу увеличится при массовых операциях ну на 5% не более. При выполнении скрипта UPDATE, оптимизатор запросов построит просто замечательный план с индекс сиками по 2 полям. Если я не прав - план запроса с костами в студию.
            Ответить
    • Секрет вечной молодости - уронить сервер на один день.
      Ответить
    • А почему нельзя просто делать проверку по типу:
      if(currentmillis()-18*3600*365*24>birthday) {
          // ADULT
      }
      ?
      Ответить
      • А у вас високосный год отклеился!
        Ответить
      • if(currentmillis()-18*3600*365*24>birthday) {
            // ADULT
        } else if(currentmillis()-30*3600*365*24>birthday) {
            // MILF
        } else if(currentmillis()-40*3600*365*24>birthday) {
            // MATURE
        } else if(currentmillis()-60*3600*365*24>birthday) {
            // GRANNY
        }
        Ответить
        • // todo: add support for:
          // LOLI
          // JAILBAIT


          чо-чо? откуда хайлатер знает такие слова? ай-ай-ай, страйко...
          Ответить
        • Не хватает баз данных системной модуляции
          Ответить
    • пива не продадут никому!
      Ответить
    • Через жопу как-то
      Ответить
    • показать все, что скрытоvanished
      Ответить

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