Utilisation de sous-requêtes avec Direct Discovery

Si la cardinalité du champ clé de jointure de la table est élevée (autrement dit, le champ contient un grand nombre de valeurs distinctes), il se peut qu'une sélection effectuée dans QlikView génère une très grande instruction SQL, car la clause WHERE key_field IN peut inclure un nombre de valeurs très important. Dans ce cas, une solution possible consiste à laisser QlikView créer des sous-requêtes à la place.

Pour illustrer ce cas de figure, nous avons utilisé un exemple dans lequel une table de produits (ProductTable) est liée à une table de commande d'articles (SalesOrderDetail) au moyen d'un ID de produit (ProductID), les deux tables étant utilisées en mode Direct Discovery.

Two linked tables.

Nous créons un graphique utilisant le mois de la commande OrderMonth comme dimension et la somme des sous-totaux Sum(Subtotal) comme mesure, ainsi qu'une zone de filtre permettant de sélectionner la taille Size.

A filter box, a bar chart and a table.

Scénario 1: faible cardinalité

Dans ce scénario, la table de produits contient un nombre réduit de produits distincts, soit 266. Si nous effectuons une sélection dans la zone Size, Direct Discovery génère une instruction SQL pour renvoyer les données en utilisant une clause WHERE ProductID IN contenant les ID de produit correspondant à la taille sélectionnée, soit 20 produits dans notre cas.

A filter box with selections made,  a bar chart and a table.

L'instruction SQL générée a l'aspect suivant :

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])

Scénario 2: utilisation de sous-requêtes

Si le même exemple contient un nombre élevé de produits distincts, par exemple 20 000, la sélection d'un filtre de dimension, tel que Size, générerait alors une instruction SQL dont la clause WHERE ProductID IN contiendrait des milliers d'ID de produit. L'instruction résultante risquerait d'être trop grande pour être gérée par la source de données du fait de limitations ou de problèmes au niveau de la mémoire ou des performances.

La solution consiste à laisser QlikView créer des sous-requêtes à la place, en définissant DirectEnableSubquery sur true. L'instruction SQL générée ressemblerait alors à celle-ci :

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])
 

La taille de la clause WHERE ProductID IN ne dépend plus alors du nombre de clés résultant de la sélection.

Les limitations suivantes s'appliquent à l'utilisation de sous-requêtes :

  • La syntaxe des sous-requêtes est uniquement appelée lorsque vous sélectionnez des données impliquant le filtrage d'un graphique à l'aide de données issues d'une autre table.
  • C'est la quantité de données incluses dans les clés, pas le nombre de clés, qui est déterminante.
  • Les sous-requêtes sont uniquement appelées lorsque toutes les tables impliquées sont en mode Direct Discovery. Si vous filtrez le graphique à l'aide de données issues d'une table incluse en mode mémoire, une clause IN sera générée.