2012-12-18 13 views
5

Dostrajam aplikację uruchamianą na App Engine i jednym z największych kosztów jest odczyt i zapis danych w magazynie danych. Zauważyłem, że jednym z największych przestępców z pism jest, gdy utrzymujemy zamówienie.W jaki sposób można zoptymalizować bazę danych Java/JDO AppEngine put(), aby zużywać mniej zapisów

Podstawowe dane jest Zakon posiada wiele elementów - możemy przechowywać zarówno oddzielnie i odnosić je tak:

@PersistenceCapable 
public class Order implements Serializable { 

    @Persistent(mappedBy="order") 
    @Element(dependent = "true") 
    private List<Item> orderItems; 

    // other fields too obviously 
} 

@PersistenceCapable 
public class Item implements Serializable { 

    @Persistent(dependent = "true") 
    @JsonIgnore 
    private Order order; 

    // more fields... 

} 

The appstats pokazuje dwa magazyn danych stawia na celu z jednej pozycji - ale obie są za pomocą masywny liczba zapisów. Chcę poznać najlepszy sposób na optymalizację tego od każdego, kto ma doświadczenie.

AppStats danych:

rzeczywiste = 34ms API = 1695ms koszt = 6400 billed_ops = [DATASTORE_WRITE: 64]

rzeczywistym = 42ms API = 995ms koszt = 3600 billed_ops = [DATASTORE_WRITE: 36]

appstats request info

Niektóre obszary znam, że prawdopodobnie będzie pomóc:

  1. mniej indeksów - istnieją implicite indeksy na kilku właściwościach zamówienia i towarów, które mogłem powiedzieć, że nie można indeksować, np. Item.quantity nie jest czymś, o co muszę pytać. Ale po to są te wszystkie zapiski?
  2. Pozbyć się elementu i porządku, tak że po prostu mam pojedynczy element OrderItem, usuwając potrzebę związku w ogóle (ale płacąc za to z dodatkową pamięcią).
  3. Pod względem wskaźników jasności mam tylko 1 na tabeli zamówień, według daty zamówienia i jednej pozycji zamówienia, według SKU/daty i implikowanej dla relacji.
  4. Jeśli przedmioty byłyby zbiorem, a nie listą, czyżby to całkowicie wyeliminowało potrzebę indeksowania dzieci _IDX?

Moje pytanie brzmi, czy któryś z powyższych elementów będzie zwiastunem wielkich wygranych, czy też są inne opcje, które przeoczyłem, na czym lepiej byłoby najpierw się skoncentrować?

Dodatkowe punkty: Czy istnieje dobry przewodnik po mniejszej przesyłce danych, który zawiera artykuł ""?

Odpowiedz

2

Billing docs wyraźnie podać:

  • Nowy Podmiot Put (za podmiot, niezależnie od wielkości podmiotu): 2 zapisuje + 2 pisze za indeksowane wartości nieruchomości + 1 Napisz za kompozytowych wartości indeksu

  • istniejącego Entity Put (na jednostkę): 1 write + 4 zapisy na zmodyfikowaną indeksowaną wartość właściwości + 2 zapisy na zmodyfikowaną wartość indeksu złożonego

  • Dotyczy również: App Engine predefines a simple index on each property of an entity.

On do pytania:

  1. Tak, liczba ops zapisu jest związana z liczbą indeksów właściwości. Zrób je unindexed to save write ops.
  2. Łącząc dwie jednostki, zaoszczędzilibyśmy 1 zapis (lub 2 w przypadku nowych obiektów).
  3. Nie musisz mieć "wyraźnych" indeksów tylko dla jednej właściwości. Są one generowane automatycznie przez appengine. Musisz tylko jawnie skonfigurować indeksy złożone, obejmujące więcej właściwości.
  4. Nie. Kolekcja lub lista (= Kolekcja z zamówieniem) to tylko reprezentacja Java, interfejs Datastore API zawsze używa listy wewnętrznie (= dodane elementy zachowują swoje zamówienie).

Aktualizacja:

Ilość indeksów wpływa koszt pisać, ale nie jest to prędkość. Writes are done in two phases: faza zatwierdzenia, w której dane obiektu są zapisywane, i stosuj fazę, w której budowane są indeksy. Operacja put powraca po fazie zatwierdzenia i nie ma wpływu na liczbę indeksów.

W twoim przypadku dzwonisz dwa razy, jeden po drugim. Jak widać na wykresie AppStats, występują one kolejno. Możesz wykonać je równolegle jako async operations (nie wiesz, czy jest dostępny w JDO).

+0

Dzięki Peter, czy są jakieś kroki poza 4 Zauważyłem, że sugerujesz zaglądanie, czy jestem na dobrej drodze z tym, co mam na myśli. –

+0

@Ashley: Zaktualizowałem odpowiedź najważniejszą informacją - liczba indeksów wpływa na koszt zapisu, ale nie na szybkość zapisu. Aby przyspieszyć sprawę, zobacz operacje asynchroniczne. –