En este documento, se describen las prácticas recomendadas para ajustar el rendimiento de las consultas de Spanner Graph, lo que incluye las siguientes optimizaciones:
- Evita un análisis completo de la tabla de entrada para nodos y aristas.
- Reducir la cantidad de datos que la consulta necesita leer del almacenamiento
- Reduce el tamaño de los datos intermedios.
Comienza con los nodos de menor cardinalidad
Escribe el recorrido de ruta de acceso de modo que comience con los nodos de menor cardinalidad. Este enfoque mantiene pequeño el conjunto de resultados intermedios y acelera la ejecución de la consulta.
Por ejemplo, las siguientes consultas tienen la misma semántica:
Recorrido de borde hacia adelante:
GRAPH FinGraph MATCH (p:Person {name:"Alex"})-[:Owns]->(a:Account {is_blocked: true}) RETURN p.id AS person_id, a.id AS account_id;Recorrido de borde inverso:
GRAPH FinGraph MATCH (a:Account {is_blocked:true})<-[:Owns]-(p:Person {name: "Alex"}) RETURN p.id AS person_id, a.id AS account_id;
Suponiendo que hay menos personas con el nombre Alex que cuentas bloqueadas, te recomendamos que escribas esta consulta en el recorrido de borde hacia adelante.
Comenzar con nodos de menor cardinalidad es especialmente importante para el recorrido de rutas de longitud variable. En el siguiente ejemplo, se muestra la forma recomendada de encontrar cuentas que estén a tres transferencias de una cuenta determinada.
GRAPH FinGraph
MATCH (:Account {id: 7})-[:Transfers]->{1,3}(a:Account)
RETURN a.id;
Especificar todas las etiquetas de forma predeterminada
Spanner Graph infiere los nodos aptos y las etiquetas de borde si se omiten las etiquetas. Te recomendamos que especifiques etiquetas para todos los nodos y bordes siempre que sea posible, ya que esta inferencia no siempre es posible y puede hacer que se analicen más etiquetas de las necesarias.
Una sola declaración MATCH
En el siguiente ejemplo, se buscan las cuentas vinculadas por un máximo de 3 transferencias desde la cuenta determinada:
GRAPH FinGraph
MATCH (src:Account {id: 7})-[:Transfers]->{1,3}(dst:Account)
RETURN dst.id;
En todas las declaraciones MATCH
Especifica etiquetas en los nodos y los bordes cuando se refieran al mismo elemento, pero se encuentren en diferentes instrucciones MATCH.
En el siguiente ejemplo, se muestra este enfoque recomendado:
GRAPH FinGraph
MATCH (acct:Account {id: 7})-[:Transfers]->{1,3}(other_acct:Account)
RETURN acct, COUNT(DISTINCT other_acct) AS related_accts
GROUP BY acct
NEXT
MATCH (acct:Account)<-[:Owns]-(p:Person)
RETURN p.id AS person, acct.id AS acct, related_accts;
Usa IS_FIRST para optimizar las preguntas
Puedes usar la función IS_FIRST para mejorar el rendimiento de las consultas tomando muestras de las aristas y limitando los recorridos en los gráficos. Esta función ayuda a controlar los nodos de alta cardinalidad y a optimizar las consultas de múltiples saltos.
Si el tamaño de la muestra que especificaste es demasiado pequeño, es posible que la consulta no devuelva datos. Por este motivo, es posible que debas probar diferentes tamaños de muestra para encontrar el equilibrio óptimo entre los datos devueltos y el rendimiento mejorado de las consultas.
En estos ejemplos de IS_FIRST, se usa FinGraph, un gráfico financiero con nodos Account y aristas Transfers para las transferencias de dinero. Para crear el FinGraph y usarlo para ejecutar las consultas de muestra, consulta Configurar y consultar Spanner Graph.
Limita los bordes recorridos para mejorar el rendimiento de las consultas
Cuando consultas gráficos, algunos nodos pueden tener una cantidad significativamente mayor de aristas entrantes o salientes en comparación con otros nodos. A veces, estos nodos de alta cardinalidad se denominan supernodos o nodos centrales. Los supernodos pueden causar problemas de rendimiento porque los recorridos a través de ellos pueden implicar el procesamiento de grandes cantidades de datos, lo que genera una distorsión de los datos y tiempos de ejecución prolongados.
Para optimizar una consulta de un gráfico con supernodos, usa la función IS_FIRST dentro de una cláusula FILTER para limitar la cantidad de aristas que atraviesa la consulta desde un nodo. Dado que las cuentas de FinGraph pueden tener cantidades significativamente más altas de transacciones que otras, puedes usar IS_FIRST para evitar una consulta ineficiente. Esta técnica es especialmente útil cuando no necesitas una enumeración completa de todas las conexiones desde un supernodo.
La siguiente consulta busca cuentas (a2) que reciben transferencias directa o indirectamente de cuentas bloqueadas (a1). La consulta usa IS_FIRST para evitar un rendimiento lento cuando una cuenta tiene muchas transferencias, ya que limita la cantidad de bordes Transfers que se deben tener en cuenta para cada Account.
GRAPH FinGraph
MATCH
(a1:Account {is_blocked: true})
-[e:Transfers WHERE e IN
{
MATCH -[selected_e:Transfers]->
FILTER IS_FIRST(@max_transfers_per_account) OVER (
PARTITION BY SOURCE_NODE_ID(selected_e)
ORDER BY selected_e.create_time DESC)
RETURN selected_e
}
]->{1,5}
(a2:Account)
RETURN a1.id AS src_id, a2.id AS dst_id;
En este ejemplo, se usan los siguientes elementos:
@max_transfers_per_account: Es un parámetro de consulta que especifica la cantidad máxima de aristasTransfersque se deben tener en cuenta para cada cuenta (a1).PARTITION BY SOURCE_NODE_ID(selected_e): Garantiza que el límite deIS_FIRSTse aplique de forma independiente para cada cuenta (a1).ORDER BY selected_e.create_time DESC: Especifica que se devuelven las transferencias más recientes.
Muestrea nodos intermedios para optimizar las consultas de múltiples saltos
También puedes mejorar la eficiencia de las consultas usando IS_FIRST para muestrear nodos intermedios en consultas de múltiples saltos. Esta técnica mejora la eficiencia, ya que limita la cantidad de rutas que la búsqueda considera para cada nodo intermedio. Para ello, divide una consulta de múltiples saltos en varias sentencias MATCH separadas por NEXT y aplica IS_FIRST en el punto medio en el que necesitas realizar el muestreo:
GRAPH FinGraph
MATCH (a1:Account {is_blocked: true})-[e1:Transfers]->(a2:Account)
FILTER IS_FIRST(1) OVER (PARTITION BY a2)
RETURN a1, a2
NEXT
MATCH (a2)-[e2:Transfers]->(a3:Account)
RETURN a1.id AS src_id, a2.id AS mid_id, a3.id AS dst_id;
Para comprender cómo IS_FIRST optimiza esta consulta, ten en cuenta lo siguiente:
La cláusula
FILTER IS_FIRST(1) OVER (PARTITION BY a2)se aplica en la primera instrucciónMATCH.Para cada nodo de cuenta intermedio (
a2),IS_FIRSTsolo considera la primera arista entranteTransfers(e1), lo que reduce la cantidad de rutas para explorar en la segunda instrucciónMATCH.Se mejora la eficiencia general de la consulta de dos saltos porque el segundo
MATCHno procesa datos innecesarios, en especial cuandoa2tiene muchas transferencias entrantes.
¿Qué sigue?
- Obtén información para consultar gráficos de propiedades en Spanner Graph.
- Migra a Spanner Graph.