2012-07-10 22 views
8

Necesito recuperar algunos datos en base a una palabra clave, la consulta se prueba al 100% de precisión, pero el problema es que la carga del reader es bastante lenta. He intentado reemplazar esta consulta con una que no contiene inner join s en absoluto y la carga fue bastante rápida. Entonces me pregunto, dado que solo estoy seleccionando una columna como resultado, ¿por qué DataTable.Load() toma tanto tiempo? ¿Es el SQLite de ExecuteReader que carga los resultados completos y no solo una columna?La carga del lector DataTable es muy lenta

Antes de usar la DataTable, el tiempo promedio de ejecución de cada reader.Read() fue de 7 segundos.

Este es mi código:

_database.Connect(); 

var selectCommand = new SQLiteCommand(
@"SELECT A.ID AS MY_ID FROM MD 
INNER JOIN TMD ON MD.ID = TMD.ID_MD 
INNER JOIN TR ON TR.ID = TMD.ID_TR 
INNER JOIN P ON P.ID = TR.ID_P 
INNER JOIN DP ON DP.ID_P = P.ID 
INNER JOIN CD ON CD.ID = DP.ID_CD 
WHERE CD.DESC = @desc" 
); 

selectCommand.Parameters.AddWithValue("@desc", value); 

using (DbDataReader reader = _database.ExecuteQuery(selectCommand)) 
{ 
    DataTable data = new DataTable("MyData"); 
    data.Load(reader); 
} 
_database.Disconnect(); 
+1

Parece que su consulta es simplemente lenta. ¿Hay alguna manera diferente de acceder a sus tablas para que no tenga que hacer tantas combinaciones? – Tejs

+0

Sabía que esto iba a doler ... Desafortunadamente tenemos que conectar las 2 tablas basadas en uno de los campos. Estas uniones son la única conexión entre ellas, dado el esquema DB actual. – iCantSeeSharp

+0

¿Qué es '_database' y por qué tiene métodos como' Connect' y 'Disconnect'? No reinventar la rueda. También debe usar un 'statement-using' para su conexión para asegurarse de que se" cierra "tan pronto como sea posible. ¿Es este un entorno multihilo como ASP.NET? –

Respuesta

2

The SQLite Query Planner ofrece algunos consejos sobre la optimización de consultas para SQLite.

Algunos elementos que pueden aplicarse a su pregunta:

1.) Debido a la implementación en SQLite usted puede tratar de volver a pedir el múltiplo une:

La implementación actual de SQLite utiliza solamente lazo se une. Es decir, decir, las uniones se implementan como bucles anidados. El orden predeterminado de los bucles anidados en una unión es para la tabla de la izquierda en la cláusula FROM a del bucle externo y la tabla de la derecha para formar el bucle interno.

Dependiendo de cómo se construyan las UNIONES, puede haber una diferencia en el rendimiento.

SQLite trata de optimizar esto automáticamente, pero por lo que he entendido la documentación que no hay garantía de éxito (destacados por mí):

Sin embargo, SQLite nido de los bucles en un orden diferente si al hacerlo entonces lo ayudará a seleccionar mejores índices. [...] Unir el reordenamiento es automático y generalmente funciona lo suficientemente bien como para que los programadores no tengan que pensar en ello, especialmente si ANALYZE se ha utilizado para recopilar estadísticas sobre los índices disponibles. Pero ocasionalmente se necesitan algunos consejos del programador .

2.) También, tenga en cuenta que combinaciones internas se convierten internamente en las cláusulas WHERE, por lo que ninguna de las sugerencias de rendimiento en la cuales pueden aplicarse sección del documento, también:

El EN y las cláusulas USING de una unión interna se convierten en términos adicionales de la cláusula WHERE antes del análisis de cláusula WHERE descrito anteriormente en el párrafo 1.0. Por lo tanto, con SQLite, no existe la ventaja computacional para usar la sintaxis de unión SQL92 más nueva sobre la sintaxis de combinación de comandos SQL89 anterior .Ambos terminan logrando exactamente lo mismo en las uniones internas.

3.) Usted podría considerar para seleccionar más columnas en su estado de cuenta, si hay índices en ellos:

No es necesario que cada columna de un índice para aparecer en una DONDE término de la cláusula para que se use ese índice. Pero no hay brechas en las columnas del índice que se utilizan.

+0

Todas las combinaciones se basan en claves principales, creo que esto resuelve el problema de la indexación, pero realmente estoy tratando de pensar si 1 + 2 podría ser un salvavidas para mi caso. – iCantSeeSharp

+0

Utilicé 'ANALYZE' antes de mi comando sql y la consulta se ejecutó bastante rápido. Entonces, teniendo en cuenta que proporcionaste la dirección correcta para este problema específico, obtienes la respuesta. ¡Gracias! – iCantSeeSharp

3

Creo que esto sucede debido a la naturaleza de SQLite y un gran número de uniones.

Trate de refactorizar el esquema de la base de datos, como desnormalizar los datos para un acceso más rápido.

+0

¿La "naturaleza de SQLite" significa que los resultados esperados son diferentes de los que se devuelven actualmente? – iCantSeeSharp

+0

@Souvlaki: Quiero decir que SQLite no soporta una buena carga para tal cantidad de uniones, también puede tener un archivo grande que degrada la permanencia resultante también. – abatishchev

+0

¿Aunque la consulta es bastante rápida en Navicat? – iCantSeeSharp

Cuestiones relacionadas