2012-01-14 19 views
8

Estoy probando RavenDB para mis proyectos futuros. El rendimiento de la base de datos es un requisito imprescindible para mí, por eso quiero ser capaz de ajustar RavenDB al menos en el rango de rendimiento de SQL Server, pero mis pruebas muestran que Raven DB es aproximadamente 10x-20x más lento en consultas seleccionadas que SQL Server, incluso cuando RavenDB está indexado y SQL Server no tiene ningún índice.Rendimiento de selección pobre RavenDB

He llenado la base de datos con 150k documentos. Cada documento tiene una colección de elementos secundarios. El tamaño de Db es aprox. 1GB y también el tamaño del índice. Cuervo/esent/CacheSizeMax se establece en 2048 y Raven/esent/MaxVerPages se establece en 128. Así es como los documentos se parece a:

{ 
    "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; } 
} 

Aquí está el índice definido:

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 } 

he definido el index utilizando Management Studio, no desde el código BTW (no sé si tiene algún efecto negativo/positivo en el rendimiento).

Esta consulta tarda de 500ms a 1500ms en completarse (Tenga en cuenta que este es el tiempo necesario para ejecutar la consulta directamente desde la consola de ravendb. No contiene el tiempo de solicitud http ni la sobrecarga de deserialización. hora).

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

Estoy ejecutando la consulta en quad core i5 cpu corriendo a 4.2 GHz y el db se encuentra en una SSD.

Ahora cuando he poblado la misma cantidad de datos en sql server express, con el mismo esquema y la misma cantidad de objetos asociados. sin índice, el servidor sql ejecuta la misma consulta que incluye combinaciones en 35 ms. Con índice toma 0ms: |.

Todas las pruebas se realizaron cuando los servidores db se calentaron.

Aunque todavía estoy muy satisfecho con el rendimiento de RavenDB, tengo curiosidad de saber si me falta algo o si RavenDB es más lento que una base de datos relacional. Lo siento por mi pobre inglés.

Gracias

ACTUALIZACIÓN

Ayande, yo tratamos de lo que usted sugiere, pero cuando intento de definir el índice que me enviaron, me sale el siguiente error:

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"); 
    } 
} 

de error CS1977: No se puede usar una expresión lambda como argumento para una operación distribuida dinámicamente sin primero enviarla a un delegado o árbol de expresiones tipo

+0

Sorprendido de ver un rendimiento pobre de Raven DB. Esto indicaría que hay un problema grave con la estructura de datos subyacente o la definición del índice. –

+1

Davita, esto no parece correcto en absoluto. Las consultas como esa deben tomar un máximo de 50 ms o menos. –

+1

¿Puedes crear un caso de prueba reproducible y enviarlo a la lista de correo? Valoramos el rendimiento muy alto y tratamos esos escenarios como errores. Por lo que vale, su escenario está dentro de nuestros parámetros de operación, y los números que cita están muy por fuera de lo que experimentamos, entonces algo está mal aquí. Un caso de prueba sería muy útil para descubrir qué está pasando –

Respuesta

6

Davita, el siguiente índice generar ~ 8 millones de entradas de índice:

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 } 

Ésta genera muchos menos:

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 } 

Y se pueden consultar con los mismos resultados, pero en nuestras pruebas se presentaron ser aproximadamente el doble de rápido

El principal problema es que está haciendo varias consultas de rango, que son costosas con una gran cantidad de valores potenciales, y luego tiene una gran cantidad de coincidencias reales para la consulta.

Hacer una coincidencia exacta es significativamente más rápido, por cierto.

Todavía estamos trabajando en formas de tratar de acelerar las cosas.

+0

Gracias Ayende, comprobaré la solución en unas pocas horas y le permitiremos conocer los resultados. Sin embargo, sería genial si pudiéramos acelerar las búsquedas indexadas, creo que 8 millones de entradas son para ralentizar DBMS. De todos modos muchas gracias por su gran trabajo y soporte:) – Davita

+0

El problema no está en el número de entradas, sino en el tipo de consulta. Tenemos que mantener muchos datos en memoria para esto, y es costoso. –

+0

Pruebe esto con una coincidencia exacta, o solo con una consulta de rango único, y verá una gran diferencia. –

Cuestiones relacionadas