Вы помещаете свои вычисления на Ваши наборы, или Ваш добирается.

Вам нужно будет выполнить два шага.

Сначала скопируйте строки в новую таблицу. Вы можете использовать оператор CREATE..AS SELECT (но после этого вам потребуется заново создать индексы и другие объекты, такие как ограничения, для новой таблицы).

CREATE TABLE  new_table
AS SELECT * FROM old_table WHERE time > '2019-01-01

Затем удалите записи из старой таблицы. Похоже, что эффективным способом было бы присоединиться к новой таблице, используя синтаксис DELETE ... USING. Предполагая, что у вас есть первичный ключ с именем id:

DELETE FROM old_table o
USING new_table n
WHERE n.id = o.id

(Обязательно создайте индекс для id в новой таблице перед запуском этого).

9
задан BobbyShaftoe 15 January 2009 в 05:06
поделиться

13 ответов

Существуют компромиссы. Если простые вычисления и не занимают много времени, то вставленный в него получение. Это делает Вашу жизнь легче, потому что Вы не должны волноваться о выполнении регистрации каждого установленного, на котором общая цена является иждивенцем, который мог привести к ошибкам.

Если вычисление занимает много времени, то Вы могли также проявить гибридный подход. Вы могли установить булевскую переменную IsDirtyTotalPrice во всех подчиненных наборах, и затем сделать вычисление на лету в получении и кэшировать его так, чтобы получение только вычислило переменную, когда это должно. Вы не делаете вычисления в наборах, потому что могли быть многие из них и Вас бледны, чтобы сделать вычисление как несколько раз как возможное.

  public class Order
  {
     private double _totalCash;
     private double _price;
     private double _quantity;
     private _IsDirtyTotalCash = true;

  private void CalcCashTotal()
  {
    _totalCash = _price * _quantity
  }

  public double Price
  {      
   set
   {
     _price = value;
     _IsDirtyTotalCash = true;
   }
  }

  public double Quantity
  {      
   set
   {
     _price = value;
     _IsDirtyTotalCash = true;
   }
  }

  public double TotalCash
  {      
   get
   {
        if(_IsDirtyTotalCash)
    {
      _totalCash = CalcTotalCost();
       _isDirtyTotalCash = false;
     }
     return _totalCash;
   }
  }

}
14
ответ дан 4 December 2019 в 06:57
поделиться

Я пошел бы с подходом выполнения вычисления в методе считывания для TotalCash, потому что меньше кода почти всегда лучше. Это также гарантирует, что значение TotalCash всегда правильно. Как изобретенный пример, если у Вас был другой метод NewOrder (Цена, Количество) и Вы забыли называть CalculateTotal в конце этого метода, Вы могли очень легко закончить с неправильным значением для TotalCash.

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

0
ответ дан 4 December 2019 в 06:57
поделиться

Я помещу вычисление на только для чтения, добираются или набор.

Я имею мнение, что свойство должно вести себя как он, имеет отступающую переменную.

Мне не нравятся вычисления, которые занимают много времени на чтениях.

0
ответ дан 4 December 2019 в 06:57
поделиться

Первое, потому что:
1) Меньше кода лучше;
2) Меньше сложности;
3) Меньше переменных помогает получить меньше сопутствующих проблем;
4) Свойство будет всегда обновляться;
5) При изменении имени процедуры "CalcCashTotal", Вы получаете больше, другой указывает на изменение...

2
ответ дан 4 December 2019 в 06:57
поделиться

Мне всегда говорили что, если существует значительная работа или сделанное вычисление, что необходимо сделать это в методе. Нет никаких главных преимуществ компилятора/времени выполнения насколько я знаю, но это будет иметь больше смысла потребителю кода. Свойство, которое требует времени для возвращения значения мне, подбросило бы красный флаг, что что-то могло быть неправильным.

Это составляет мои 2 цента..., но даже я, вероятно, просто пошел бы с Вашим первым примером, если класс действительно настолько прост :-)

1
ответ дан 4 December 2019 в 06:57
поделиться

Первый вариант лучше. Различие в "оптимизации" является крохотным. Не говоря уже о, что, если установка происходит много раз, но только когда-либо необходимо получать TotalCost однажды? Я был бы более обеспокоен потерянными часами разработчика, пытаясь отладить класс, после того как это становится очень сложным.

Но существует важное время, когда вторая опция необходима, конкретно когда расчетное значение изменяет расчетные объекты. Мне приходится нелегко придумывающий пример, таким образом, я буду использовать реальный, где количество отсеков в стене определяется ее шириной.

class Wall {
    public decimal Width {
       get {
           ...
       }
       set {
           ValidateChanges();
           width = value;
           CreateBays();
       }
    }

    public Bays[] Bays {
       get {
           ...
       }
       set {
           ValidateChanges();
           ...
       }
    }

    private void CreateBays() {
        // Delete all the old bays.
        ...
        // Create a new bay per spacing interval given the wall width.
        ...
    }
}

Здесь, каждый раз, когда ширина изменяется, отсеки в стене воссоздаются. Если бы это произошло на Bay.getter, то это довольно имело бы катастрофические последствия для свойств объекта Отсека. Метод считывания должен был бы выяснить, изменилась ли ширина или не, так как последние получают оператор, увеличивая сложность.

1
ответ дан 4 December 2019 в 06:57
поделиться

При определении, должно ли свойство быть получено/вычислено, важно рассмотреть, должно ли значение во время вычисления быть сохранено.

В этом случае TotalCash - если изменения бизнес-логики для вычисления, имея изменение свойства TotalCash задним числом для существующих записей не могут быть желательными.

просто помещение его там...

3
ответ дан 4 December 2019 в 06:57
поделиться

Я пошел бы с гибридным предложением Charles Graham, но я хочу добавить свои два цента относительно почему.

Много вышеупомянутых предложений говорит о сложности и оптимизации, но забывает, что это все идет из окна, когда Вы включаете в потребителя своего класса. Если бы Вы - единственный потребитель, и Вы использовали первую реализацию, возможности - Вы, не забыл бы:

double subTotal = myOrder.TotalCash;
double tax = subTotal * 0.05;
double shipping = subTotal > 100 ? 0 : 5.95;
double grandTotal = subTotal + tax + shipping;
OutputToUser(subTotal, tax, shipping, grandTotal);

Другие люди не могли бы. Наблюдение этого myOrder.TotalCash свойство, не метод, по крайней мере, я предположил бы, что это - кэшируемое значение. Таким образом, доступ subTotal в вышеупомянутом примере сопоставимо в эффективности как доступ myOrder.TotalCash. Не понимание там является вычислением, продолжающимся негласно, они пишут:

double tax = myOrder.TotalCash * 0.05;
double shipping = myOrder.TotalCash > 100 ? 0 : 5.95;
double grandTotal = myOrder.TotalCash + tax + shipping;
OutputToUser(myOrder.TotalCash, tax, shipping, grandTotal);

отъезд myOrder.TotalCash обозначать промежуточный итог. Теперь, это было вычислено 4 раза вместо 1.

Таким образом, я уверен, что я не единственный, кто полагает, что свойство представляет переменное или кэшируемое значение, и метод обрабатывает что-то и возвращает значение. Имеет смысл хранить CalculateTotalCash() и только назовите его однажды, потому что Вы ожидаете, что это будет хитом производительности. С другой стороны, Вы ожидаете TotalCash быть кэшируемым значением и может получить доступ к нему по желанию. Таким образом важно только повторно вычислить TotalCash когда это изменяется.

Гибридное предложение побеждает в случае нескольких наборов между чтениями. Тем путем Вы не напрасно тратите время, вычисляя значение, которое будет выброшено.

3
ответ дан 4 December 2019 в 06:57
поделиться

Обычно я пытаюсь поместить их на набор начиная со значения, которое они генерируют, будет сохранен внутренне и только должен быть вычислен однажды. Необходимо только поставить вычисления, добираются, если значение, вероятно, изменит каждый раз свой запрошенный.

В Вашем примере цены/количества у Вас мог на самом деле быть единственный отдельный метод, который повторно вычисляет количество, когда или цена или количество установлены.

4
ответ дан 4 December 2019 в 06:57
поделиться

Первое лучше потому что:

  • Это короче.
  • Легче понять.
  • Немного самонадеянно повторно вычислить TotalCash каждый раз или цена или количество установлены. Это должно быть максимально лениво и только вычислить при необходимости.

Однако помещение вычисления в методе set эффективно кэширует его, поэтому при столкновении с проблемой производительности которая могла бы быть полезным изменением (за счет ясности).

3
ответ дан 4 December 2019 в 06:57
поделиться

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

1
ответ дан 4 December 2019 в 06:57
поделиться

Это зависит от обстоятельств. Ваше приложение тяжело читает или пишет? Расчет стоит дорого? Если вычисление является дорогостоящим и ваше приложение тяжело читается, сделайте это на множестве, таким образом вы заплатите штраф за вычисление лишь несколько раз (по сравнению с чтениями).

1
ответ дан 4 December 2019 в 06:57
поделиться

Мое правило, и я рекомендую его всем:

Методы = с побочными эффектами Геттеры = без побочных эффектов (ИСКЛЮЧАЯ мемоизацию - которая разрешена и в геттерах)

0
ответ дан 4 December 2019 в 06:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: