2012-01-14 19 views
8

Sto testando RavenDB per i miei progetti futuri. Le prestazioni del database sono un requisito irrinunciabile per me, ecco perché voglio essere in grado di sintonizzare RavenDB almeno nella gamma delle prestazioni di SQL Server, ma i miei test mostrano che Raven db è approssimativamente 10x-20x più lento nelle query selezionate di SQL Server, anche quando RavenDB è indicizzato e SQL Server non ha indici.RavenDB scarse prestazioni selezionate

Ho popolato il database con 150k di documenti. Ogni documento ha una collezione di elementi figlio. Dimensione Db è di ca. 1 GB e anche la dimensione dell'indice. Raven/ESENT/CacheSizeMax è impostato a 2048 e Raven/ESENT/MaxVerPages è impostato su 128. Ecco come i documenti appare come:

{ 
    "Date": "2028-09-29T01:27:13.7981628", 
    "Items": [ 
    { 
     { 
     "ProductId": "products/673", 
     "Quantity": 26, 
     "Price": { 
     "Amount": 2443.0, 
     "Currency": "USD" 
     } 
    }, 
    { 
     "ProductId": "products/649", 
     "Quantity": 10, 
     "Price": { 
     "Amount": 1642.0, 
     "Currency": "USD" 
     } 
    } 
    ], 
    "CustomerId": "customers/10" 
} 


public class Order 
{ 
    public DateTime Date { get; set; } 
    public IList<OrderItem> Items { get; set; } 
    public string CustomerId { get; set; } 
} 

public class OrderItem 
{ 
    public string ProductId { get; set; } 
    public int Quantity { get; set; } 
    public Price Price { get; set; } 
} 

public class Price 
{ 
    public decimal Amount { get; set; } 
    public string Currency { get; set; } 
} 

Ecco l'indice definito:

from doc in docs.Orders 
from docItemsItem in ((IEnumerable<dynamic>)doc.Items).DefaultIfEmpty() 
select new { Items_Price_Amount = docItemsItem.Price.Amount, Items_Quantity = docItemsItem.Quantity, Date = doc.Date } 

ho definito il indice usando Management Studio, non dal codice BTW (non so se ha un effetto negativo/positivo sulla perfromance).

Questa query richiede da 500ms a 1500ms per essere completata (si noti che questo è il tempo necessario per eseguire la query, mostrata direttamente dalla console di ravendb .Questo non contiene tempo di richiesta HTTP e overhead di deserializzazione. tempo).

session.Query<Order>("OrdersIndex").Where(o => 
    o.Items.Any(oi => oi.Price.Amount > 0 && oi.Quantity < 100)).Take(128).ToList(); 

che sto di eseguire la query su quad core i5 CPU funziona a 4,2 GHz e il db si trova su uno SSD.

Ora ho popolato la stessa quantità di dati su SQL Server Express, con lo stesso schema e la stessa quantità di oggetti associati. senza indice, sql server esegue la stessa query che include join in 35 ms. Con l'indice ci vogliono 0ms: |.

Tutti i test sono stati eseguiti quando i server DB sono stati riscaldati.

Tuttavia, sono ancora molto soddisfatto delle prestazioni di RavenDB, sono curioso di sapere se mi manca qualcosa o RavenDB è più lento di un database relazionale? Scusa per il mio povero inglese.

Grazie

UPDATE

Ayande, ho provato quello che lei ha suggerito, ma quando provo a definire l'indice che mi hai mandato, ottengo il seguente errore:

public Index_OrdersIndex() 
    { 
     this.ViewText = @"from doc in docs.Orders 
select new { Items_Price_Amount = doc.Items(s=>s.Price.Amount), Items_Quantity = doc.Items(s=>s.Quantity), Date = doc.Date } 
"; 
     this.ForEntityNames.Add("Orders"); 
     this.AddMapDefinition(docs => from doc in docs 
      where doc["@metadata"]["Raven-Entity-Name"] == "Orders" 
      select new { Items_Price_Amount = doc.Items(s => s.Price.Amount), Items_Quantity = doc.Items.(s => s.Quantity), Date = doc.Date, __document_id = doc.__document_id }); 
     this.AddField("Items_Price_Amount"); 
     this.AddField("Items_Quantity"); 
     this.AddField("Date"); 
     this.AddField("__document_id"); 
     this.AddQueryParameterForMap("Date"); 
     this.AddQueryParameterForMap("__document_id"); 
     this.AddQueryParameterForReduce("Date"); 
     this.AddQueryParameterForReduce("__document_id"); 
    } 
} 

errore CS1977: impossibile utilizzare un'espressione lambda come argomento per un'operazione inviata dinamicamente senza prima convertirla in un delegato o in un tipo di albero di espressioni

+0

Sorpreso di vedere prestazioni scadenti da Raven DB. Ciò indicherebbe che c'è un problema serio con la struttura dati sottostante o la definizione dell'indice. –

+1

Davita, questo non sembra proprio niente. Query del genere dovrebbero richiedere un massimo di 50 ms circa. –

+1

È possibile creare un test case riproducibile e inviarlo alla mailing list? Apprezziamo molto la perfezione e trattiamo tali scenari come bug. Per quello che vale, il tuo scenario è ben all'interno dei nostri parametri operativi, ei numeri che citi sono molto al di fuori di ciò che abbiamo vissuto, quindi qualcosa qui non va. Un test case sarebbe molto utile per capire cosa sta succedendo –

risposta

6

Davita, L'indice seguente generare ~ 8 milioni di voci di indice:

from doc in docs.Orders 
from docItemsItem in ((IEnumerable<dynamic>)doc.Items).DefaultIfEmpty() 
select new { Items_Price_Amount = docItemsItem.Price.Amount, Items_Quantity = docItemsItem.Quantity, Date = doc.Date } 

Questo genera molto meno:

from doc in docs.Orders 
select new { Items_Price_Amount = doc.Items(s=>s.Price.Amount), Items_Quantity = doc.Items.(s=>s.Quantity), Date = doc.Date } 

E possono essere interrogati con gli stessi risultati, ma sui nostri test hanno mostrato up essere circa il doppio più velocemente.

Il problema principale è che si stanno facendo diverse query raggio, che sono costosi, con un gran numero di valori possibili, e poi si dispone di un gran numero di partite reali per la query.

Facendo una corrispondenza esatta è significativamente più veloce, tra l'altro.

Stiamo ancora lavorando sui modi per cercare di accelerare le cose.

+0

Grazie Ayende, controllerò la soluzione in poche ore e ti faccio sapere i risultati, tuttavia sarebbe bello se potessimo accelerare le ricerche indicizzate, 8 milioni di voci sono così tanto per rallentare il DBMS, penso, comunque ti ringrazio molto per il tuo grande lavoro e supporto:) – Davita

+0

Il problema non è con il numero di voci, ma con il tipo di query. Dobbiamo tenere un sacco di dati in memoria per questo ed è costoso. –

+0

Prova questo con una corrispondenza esatta, o solo una query di intervallo singolo, e vedrai una grande differenza. –

Problemi correlati