Utilizar subconsultas con Direct Discovery

Si la cardinalidad del campo clave que enlaza la tabla es alta, es decir, contiene un gran número de valores distintos, una selección en QlikView podrá generar una sentencia SQL muy extensa, puesto que la cláusula WHERE key_field IN podría contener un gran número de valores. En este caso una posible solución es dejar que QlikView cree subconsultas en vez.

Para ilustrar esto, recurrimos a un ejemplo en el que una tabla de productos (ProductTable) se enlaza con una tabla de detalle de pedidos de venta (SalesOrderDetail) usando un id de producto (ProductID), con ambas tablas en modo Direct Discovery.

Creamos una tabla con OrderMonth como dimensión, y Sum(Subtotal) como medida, y un campo de filtrado para seleccionar Size.

Escenario 1: Baja cardinalidad

En este escenario, la tabla de productos contiene un número reducido de productos distintos, 266. Si hacemos una selección en Size, Direct Discovery genera una sentencia SQL para devolver los datos, usando una cláusula WHERE ProductID IN que contiene los IDs de producto que coinciden con el tamaño seleccionado, en este caso 20 productos.

La sintaxis SQL generada presenta el siguiente aspecto:

SELECT ProductID, month([OrderDate]), SUM(OrderQty), SUM(SubTotal)
FROM SalesTable
WHERE ProductID IN ( 12, 51, 67, 81, 89, 92, 100, 108, 142, 150, 151, 162, 191, 206, 220, 222, 251, 254)
GROUP BY ProductID, month([OrderDate])

Escenario 2: Utilizar subconsultas

Si el mismo ejemplo contiene un número elevado de productos distintos, por ejemplo 20.000, seleccionar un filtro de dimensiones, por ejemplo Size, generaría una sentencia SQL con una cláusula WHERE ProductID IN que contiene miles de IDs de producto. La sentencia resultante podría ser demasiado extensa para que lla gestione la fuente de datos debido a limitaciones o problemas de memoria o rendimiento.

La solución está en permitir que QlikView cree subconsultas en vez, configurando DirectEnableSubquery como verdadero. La sentencia SQL generada podría presentar el siguiente aspecto en vez:

SELECT ProductID, month([OrderDate]), SUM(OrderQty), SUM(SubTotal)
FROM SalesTable
WHERE ProductID IN
( SELECT DISTINCT "AW2012"."dbo"."PRODUCT"."PRODUCTID" WHERE "AW2012"."dbo"."PRODUCT"."SIZE" IN (3))
GROUP BY ProductID, month([OrderDate])
 

El tamaño de la cláusula WHERE ProductID IN ya no depende del número de claves que resultan de la selección.

Al utilizar subconsultas hemos de tener en cuenta las siguientes limitaciones:

  • Sólo debemos invocar la sintaxis de subconsultas cuando seleccionemos datos que impliquen filtrar un gráfico usando datos de otra tabla.
  • La cantidad de datos dentro de las claves es el factor determinante, no el número de claves.
  • Las subconsultas sólo se invocan si todas las tablas implicadas están en modo Direct Discovery. Si filtramos el gráfico utilizando datos de una tabla incluida en el modo de memoria, se generará una cláusula IN.