java - español - neo4j sql
Neo4j Cypher Query es extremadamente lento(unos 20 minutos) (2)
¿Qué tan grande es tu base de datos? ¿Cuántos usuarios tienes en tu userIndex
?
¿Cuál es tu configuración de memoria / montón? Supongo que se encontrará con una gran cantidad de problemas de GC, ya que Cypher intenta ajustar todo el DB en la memoria para sus consultas.
También en cachés fríos y poca memoria, básicamente se mide la velocidad del disco para extraer los datos en la memoria.
Puede combinar sus consultas en una sola.
START user=node:userIndex("Username:*")
RETURN has(user.FullNodeCreationTime),has(user.NumFollowers), COUNT(*) AS num
que debería devolver 4 entradas para los 4 combos que puede usar / agregar fácilmente
Todas estas no son consultas de gráficos, y también grafican consultas globales. Entonces, ni Neo4j ni Cypher están optimizados para ellos :)
Tengo un programa que abre una base de datos incrustada y ejecuta varias consultas sobre ella. Estoy usando un ExecutionEngine y reutilizándolo para cada consulta. Simplemente ejecutar las primeras 3 consultas, que son las más simples, lleva - bueno, no sé cuánto tiempo lleva, porque lo detuve después de aproximadamente 1/2 hora, después de lo cual solo hice 2 consultas. He tenido problemas con Cypher siendo lento en este gráfico antes, pero nunca ha sido tan malo. Estoy usando la API para algunas consultas más complicadas, pero prefiero usar Cypher para estos porque son muy simples. También tengo algunas otras consultas que me gustaría ejecutar que básicamente necesitan ejecutar y devolver la mayoría de la base de datos, algunos nodos varias veces ... Sé que esto no es recomendable, pero necesito que todo esté diseñado de acuerdo con sus relaciones: obtener cada nodo en el gráfico será completamente inútil. Esa consulta toma unos días, al ritmo que voy. No tengo ningún problema con lo que otras personas consideran "lento" (por ejemplo, 500 ms), b / c no es una aplicación en tiempo real, pero 20 minutos es excesivo. ¿Qué está mal? ¿Qué estoy haciendo mal?
Mi base de datos contiene varios millones de nodos y al menos tantas relaciones. Se supone que Neo4j es capaz de manejar gráficos tan grandes fácilmente. ¿Por qué estoy obteniendo tiempos de ejecución tan locos?
Si alguien puede ayudarme con esto (¿quizás mis dudas sean todas incorrectas?), ¡Realmente lo agradecería!
Gracias, bsg Aquí está el código para las primeras tres consultas que toman 30 minutos + juntas. Ejecuta cada uno e imprime el resultado (un conteo simple) en un archivo.
ExecutionEngine eng = new ExecutionEngine(graphdb);
String filepath = resultstring + "basicstats.txt";
PrintWriter basics = new PrintWriter(resultstring + "basicstats.txt");
String querystring = "START user=node:userIndex(/"Username:*/")" +
" WHERE has(user.FullNodeCreationTime) "
+ " RETURN COUNT(user) AS numcrawled";
ExecutionResult result = eng.execute(querystring);
basics.print("Number of users crawled: ");
basics.println(result.iterator().next().get("numcrawled"));
String otherusers = "START user=node:userIndex(/"Username:*/")" +
" WHERE NOT has(user.FullNodeCreationTime)" +
" RETURN COUNT(user) AS numtouched";
result = eng.execute(otherusers);
basics.print("Number of users touched (not crawled): ");
basics.println(result.iterator().next().get("numtouched"));
String partialinfousers = "START user=node:userIndex(/"Username:*/")" +
" WHERE NOT has(user.FullNodeCreationTime) AND NOT has(user.NumFollowers)" +
" RETURN COUNT(user.Username) AS numcrawled";
result = eng.execute(partialinfousers);
basics.print("Number of users with partial info: ");
basics.println(result.iterator().next().get("numcrawled"));
basics.close();
Primero, ejecute su consulta desde el shell utilizando EXPLAIN para ver cómo se está ejecutando la consulta. Ese siempre es el primer lugar para comenzar a entender los problemas de rendimiento.
En segundo lugar, si estoy entendiendo correctamente su primera consulta, simplemente quiere saber cuántos nodos tienen la propiedad FullNodeCreationTime . La consulta existente no usa realmente un índice de manera óptima, ya que no está buscando un valor específico. También parece que está mirando un tipo de nodo único, es decir, un nodo con una etiqueta específica como Usuario. Si eso es correcto, crearía un índice en User.FullNodeCreationTime y simplemente ejecutaría esta consulta:
match (u:User) where has (u.FullNodeCreationTime) return count(u)
Eso debería funcionar mucho mejor.