2010-07-28 25 views
26

La complejidad de los métodos en la mayoría de los lenguajes de programación se puede medir en complejidad ciclomática con analizadores de código fuente estático. ¿Hay una métrica similar para medir la complejidad de una consulta SQL?Medición de la complejidad de las sentencias SQL

Es lo suficientemente simple como para medir el tiempo que tarda una consulta en regresar, pero ¿qué ocurre si solo quiero poder cuantificar qué tan complicada es una consulta?

[Editar/Nota] Si bien obtener el plan de ejecución es útil, eso no es necesariamente lo que estoy tratando de identificar en este caso. No estoy buscando qué tan difícil es para el servidor ejecutar la consulta, estoy buscando una métrica que identifique lo difícil que fue para el desarrollador escribir la consulta, y qué tan probable es que contenga un defecto.

[Editar/Nota 2] Es cierto que hay momentos en los que la medición de la complejidad no es útil, pero también hay momentos en los que sí lo es. Para una discusión adicional sobre ese tema, vea this question.

+3

¿Es la complejidad del código fuente, o la complejidad del procesamiento que requiere, ¿qué le interesa medir? –

+1

Realmente me pregunto si hay una manera de medir la complejidad del código fuente. Con C#/C++/Java, a menudo uso Cyclomatic Complexity para determinar qué métodos deberían probarse primero. Aquí, me gustaría saber qué consultas necesitan la mayor atención de la prueba. – epotter

+0

¿Tiene la intención de expandir nuestras definiciones 'VIEW' en las consultas? ¿El uso de una función definida por el usuario de SQL hace que el código sea menos complejo o su definición necesita expandirse también? – onedaywhen

Respuesta

9

Las medidas comunes de la complejidad del software incluyen Cyclomatic Complexity (una medida de lo complicado que es el flujo de control) y Halstead complexity (una medida de la aritmética es compleja).

El "flujo de control" en una consulta SQL se relaciona mejor con los operadores "y" y "o" en la consulta.

La "complejidad computacional" se relaciona mejor con operadores como SUM o UNIONES implícitas.

Una vez que haya decidido cómo categorizar cada unidad de sintaxis de una consulta SQL en cuanto a si es "flujo de control" o "cálculo", puede calcular directamente las medidas de Cyclomatic o Halstead.

Lo que el optimizador de SQL hace para las consultas I piensa que es absolutamente irrelevante. El propósito de las medidas de complejidad es caracterizar qué tan difícil es para una persona entender la consulta, no cómo con qué eficacia puede evaluarse.

De manera similar, lo que dice la DDL o si las vistas están involucradas o no deben incluirse en tales medidas de complejidad. La suposición detrás de estas métricas es que la complejidad de la maquinaria dentro de una abstracción usada no es interesante cuando simplemente la invocas, porque presumiblemente esa abstracción hace algo bien entendido por el codificador. Esta es la razón por la que las medidas de Halstead y Cyclomatic no incluyen las subrutinas llamadas en su recuento, y creo que se puede argumentar que las vistas y la información de DDL son esas abstracciones "invocadas".

Por último, cuán perfectamente correcto o cuán equivocados están estos números de complejidad no importa mucho, siempre y cuando reflejen cierta verdad acerca de la complejidad y puedan compararse entre sí. De esta forma, puede elegir qué fragmentos de SQL son los más complejos, por lo tanto, clasificarlos a todos y centrar la atención de las pruebas en los más complicados.

+0

Por lo que usted sabe, ¿existe alguna herramienta de este tipo? – epotter

+0

Bueno, tipo de sí. Mi compañía ofrece un motor de búsqueda de código fuente (SCSE) (http://www.semanticdesigns.com/Products/SearchEngine) que escanea en un conjunto de archivos para preparar un índice para buscar. El SCSE pasa a calcular varias medidas simples (SLOC, CommentCount, Cyclomatic, Halstead) sobre cada archivo como un todo durante el escaneo, * y * procesará muchos idiomas, incluido PLSQL. PLSQL, por supuesto, tiene SQL como un sublenguaje, e IIRC, SCSE calcula los números de complejidad del software más o menos como he descrito anteriormente. Si coloca los fragmentos de SQL en archivos, es probable que SCSE lo haga. –

+0

... Siempre está la pregunta de * ¿dónde están tus fragmentos SQL? * Si están incrustados en fragmentos de cadena en llamadas ODBC, extraerlos y medirlos va a ser difícil porque las partes están dispersas por el código y no está Es obvio instantáneamente que cualquier literal de cadena en particular es parte de una consulta o, si es así, a dónde va. Si sus consultas SQL están integradas en un lenguaje de procedimientos almacenados como PLSQL, obviamente son mucho más fáciles de "extraer". Pero la herramienta ideal en ese caso es aquella que mide las consultas SQL por separado in situ para que no tenga que extraerlas manualmente o hackearlas. –

1

Las consultas SQL son declarativas en lugar de procedurales: no especifican cómo lograr su objetivo. El motor SQL creará un plan de ataque de procedimiento, y ese podría ser un buen lugar para buscar complejidad. Intente examinar el resultado de la declaración de EXPLAIN (o EXPLAIN PLAN), será una descripción cruda de los pasos que el motor utilizará para ejecutar su consulta.

+0

"Las consultas SQL son declarativas en lugar de procedurales", por lo que no puede considerar el SQL DML de forma aislada del SQL DDL. – onedaywhen

+0

En principio, la complejidad ciclomática podría calcularse para un plan de ejecución dando así una medida indirecta de la complejidad de la fuente SQL que lo produjo. El problema es que los planes de ejecución son típicamente una fusión que contiene la ejecución descrita por todas las 'sub-rutinas' (en este caso, vistas, funciones con valores de tabla, etc.), ¡así que tampoco funcionaría! – redcalx

0

Bueno, si estás usando SQL Server, diría que deberías mirar el costo de la consulta en el plan de ejecución (específicamente el costo del subárbol).

Here es un enlace que repasa algunas de las cosas que debe considerar en el plan de ejecución.

0

Dependiendo de su RDBMS, puede haber herramientas de plan de consulta que pueden ayudarle a analizar los pasos que el RDBMS tomará para recuperar su consulta.

SQL Server Management Studio Express tiene un plan de ejecución de consultas incorporado. Pervasive PSQL tiene su Query Plan Finder. DB2 tiene herramientas similares (olvidó cómo se llaman).

0

Una buena pregunta. El problema es que para una consulta SQL como:

SELECT * FROM foo; 

la complejidad puede depender de lo "foo" es y sobre la aplicación de base de datos. Para una función como:

int f(int n) { 
    if (n == 42) { 
     return 0; 
    } 
    else { 
     return n; 
    } 
} 

no existe tal dependencia.

Sin embargo, creo que debería ser posible obtener algunas métricas útiles para un SELECT, incluso si no son muy exactas, y me interesaría ver qué respuestas se obtienen.

+1

Estoy algo en desacuerdo sobre el ejemplo 'foo'. Eso sería como tener en cuenta la complejidad de las funciones llamadas, al medir la complejidad de un código de procedimiento. – pascal

+0

De acuerdo. La complejidad de Cyclomatic, por ejemplo, le informa sobre la cantidad de rutas posibles a través de una sección de código fuente, y en el uso normal no calcula las subrutas adicionales con sub-rutinas a las que se llama. Se trata de la complejidad de la sección de código en cuestión, es decir, qué tan legible y, por lo tanto, fácil de mantener. – redcalx

10

No estoy seguro de que la recuperación de los planes de consulta responda a la pregunta: los planes de consulta ocultan una parte de la complejidad del cálculo realizado en los datos antes de que se devuelva (o se use en un filtro); los planes de consulta requieren una base de datos significativa para ser relevante. De hecho, la complejidad y la duración de la ejecución son algo opuestos; algo como "Bueno, rápido, barato: elige dos".

¿En definitiva, se trata de las posibilidades de cometer un error o de no entender el código que he escrito?

Algo así como:?

  • número de tablas de multiplicar (1
  • 1 por unirse a la expresión (1 por cada combinación externa)
  • 1 por predicado después WHERE o HAVING
  • + 1 por GROUP BY expresión
  • +1 por UNION o INTERSECT
  • +1 por la función de llamada
  • 1 por CASE expresión
  • )
+0

Este es exactamente el tipo de cosa que estoy buscando. Si no puedo encontrar uno, podría elaborar el mío similar a esto. – epotter

+0

También podría eliminar algunos puntos (¿medio punto?) Para realizar una búsqueda en un campo indexado. Y no olvide su pedido también. – MPelletier

+0

Como alguien mencionó, esta medida no sería sobre la eficiencia de las declaraciones SQL. Se trata de su complejidad, o el riesgo que presentan para las pruebas (p. Ej., Perder un predicado o utilizar una combinación interna en lugar de una izquierda, o el infame * ¿por qué mi consulta simple tardará para siempre en ejecutarse? *, También conocida como la combinación faltante) . En ese sentido, no veo por qué debería tenerse en cuenta la presencia de un índice. – pascal

1

Bueno, yo no sé de cualquier herramienta que hizo tal cosa, pero me parece que lo que haría una consulta más complicada se mediría por: el número de combinaciones el número de donde las condiciones el número de funciones el número de subconsultas el número de moldes de tipos de datos diferentes personas el número de declaraciones de casos el número de bucles o cursores el número de pasos en una transacción

Sin embargo, si bien es cierto que las consultas más comlex pueden parecer ser las que tienen más defectos posibles, me parece que las simples son muy propensas a contener defectos ya que son es más probable que lo escriba alguien que no comprenda el modelo de datos y, por lo tanto, parezca que funciona correctamente, pero que de hecho devuelva los datos incorrectos. Así que no estoy seguro de que una métrica así te diga mucho.

+3

Como cualquier análisis de código estático, la utilidad sería limitada. Así que estoy de acuerdo con lo que estás diciendo. Pero consideremos una situación en la que un único desarrollador o tres desarrolladores igualmente calificados escribieron 20 consultas. Si fuera posible determinar qué consultas eran las más complejas y, por lo tanto, con mayor probabilidad contener defectos, las pruebas podrían enfocarse primero y/o la mayoría de las consultas. Los analizadores de códigos estáticos nunca son indicadores o corrección, solo son indicadores. Te dan algo más para oler por 'códigos huele'. – epotter

0

En ausencia de herramientas que lo hagan, un enfoque pragmático sería asegurar que las consultas que se analizan estén consistentemente formateadas y luego cuenten las líneas de código.

Como alternativa, utilice el tamaño de las consultas en bytes cuando se guardan en un archivo (teniendo cuidado de que todas las consultas se guarden con la misma codificación de caracteres).

No es genial, pero un proxy razonable para la complejidad en la ausencia de otra cosa, creo.

Cuestiones relacionadas