2016-03-23 1 views
1

Dans SQL Server, je viens de JOIN avec une instruction BETWEEN pour Éclater une plage de temps en plusieurs enregistrements d'intervalle. La requête ressemble àU-SQL - Rejoindre BETWEEN

SELECT 
    a.UltimateID, 
    a.SiteID, 
    ProductID, 
    b.Date 
FROM 
    ss_UsageTracking a 
    JOIN SELECTServerSchema.ss_fn_CreateDateTable(@StartDate, @EndDate, 1) b ON b.Date BETWEEN a.StartDate AND a.EndDate 

Cela me donne un enregistrement pour chaque donnée entre StartDate et EndDate Nous avons trouvé un moyen de le faire explosion à l'aide d'une UDF qui retourne un tableau SQL et une croix APPLIQUER déclaration EXPLOSER .

Le problème que je vois est que nous calculons la plage de dates des millions de fois, une fois par ligne dans la ligne définie. Cela semble être très inefficace et est en effet la principale source de consommation de temps lors du traitement.

J'ai créé un moyen de générer la table de dates utilisée ci-dessus et j'aimerais expérimenter sur les performances, mais les jointures U-SQL ne prennent pas en charge les instructions BETWEEN.

Quelle est l'approche qui devrait être utilisée pour cela? La documentation ne permet pas de savoir si une application CROSS peut gérer cela.

Je TENTATIVE l'aide d'une UDF dans le code derrière pour retourner true ou false si l'intervalle était entre deux dates, mais que seule a donné lieu à une erreur du JOIN sur l'article ne peut être sur des colonnes et non

UDF

Répondre

3

Le raison pour laquelle U-SQL ne prend pas en charge les expressions BETWEEN (ou autres expressions non équidépendantes) dans la clause ON de la jointure est expliqué ici: https://msdn.microsoft.com/en-us/library/azure/mt621310.aspx. En bref: Nous voulons exposer uniquement les jointures optimisables dans la syntaxe de jointure et rendre le coût d'exécution plus apparent dans les autres cas.

Vous pouvez effectuer la jointure en utilisant un CROSS JOIN et en déplaçant le prédicat BETWEEN dans la clause WHERE.

Ainsi, au lieu de

@x = SELECT * FROM t JOIN s ON t.a BETWEEN s.beg AND s.end; 

vous écrire

@x = SELECT * FROM t CROSS JOIN s WHERE t.a BETWEEN s.beg AND s.end; 

Vous pouvez aussi invoquer l'UDF dans une clause select avant la jointure puis utilisez la colonne de l'UDF dans le équijointure.

Ainsi, au lieu de

@x = SELECT * FROM t JOIN s ON f(t.a) == s.b; 

Vous écririez

@t = SELECT *, f(a) AS fa FROM t; 
@x = SELECT * FROM @t JOIN s ON t.fa == s.b; // note this includes fa in result 

Si vous sentez que vous avez plutôt U-SQL ne les réécritures pour vous, au détriment de la compréhension moins les conséquences sur les performances, veuillez déposer une demande au http://aka.ms/adlfeedback.