L'action fedsql.execdirect permet de soumettre des requêtes SQL directement au serveur CAS. En spécifiant le paramètre 'showStages=true', il est possible d'obtenir un rapport détaillé du plan d'exécution de la requête. Ce rapport décompose l'exécution en plusieurs étapes, affichant les méthodes utilisées (par exemple, tri, agrégation, balayage séquentiel), la requête SQL générée pour chaque étape (stage query), le nombre de threads d'accès aux données par worker, les tables d'entrée avec leurs propriétés (nombre de lignes, colonnes, partitionnement), et les temps d'exécution pour chaque étape et pour la requête globale. Cette information est cruciale pour l'optimisation des requêtes et la compréhension du comportement de FedSQL sur l'architecture distribuée de CAS.
Analyse des données
Type : CREATION_INTERNE
Les exemples utilisent une table 'crimeCensus' créée de manière interne avec un DATA Step et des données fictives pour simuler le comportement décrit dans la documentation.
1 Bloc de code
DATA STEP / FEDSQL.EXECDIRECT Data
Explication : Cet exemple minimal crée une table temporaire 'crimeCensus' dans CASUSER avec des données fictives. Ensuite, il exécute une simple requête FedSQL qui compte le nombre d'occurrences pour chaque 'primary_type' et trie les résultats par ordre décroissant du compte. Le paramètre 'showStages' n'est pas utilisé ici pour illustrer l'utilisation basique de l'action.
Copié !
data casuser.crimeCensus;
infile datalines dlm=';';
input primary_type $ date :yymmdd10. community_area hardship_index per_capita_income;
format date yymmdd10.;
datalines;
THEFT;2015-01-15;10;80;25000
THEFT;2015-02-20;10;80;25000
THEFT;2015-03-01;10;80;25000
THEFT;2015-04-10;10;80;25000
THEFT;2015-05-05;10;80;25000
THEFT;2016-01-20;10;80;25000
THEFT;2016-02-25;10;80;25000
THEFT;2016-03-05;10;80;25000
THEFT;2016-04-15;10;80;25000
THEFT;2016-05-10;10;80;25000
ASSAULT;2015-01-01;20;70;30000
ASSAULT;2015-01-02;20;70;30000
ASSAULT;2015-01-03;20;70;30000
ASSAULT;2015-01-04;20;70;30000
ASSAULT;2015-01-05;20;70;30000
ROBBERY;2016-06-01;30;90;20000
ROBBERY;2016-06-02;30;90;20000
ROBBERY;2016-06-03;30;90;20000
ROBBERY;2016-06-04;30;90;20000
ROBBERY;2016-06-05;30;90;20000
;
run;
proc cas;
fedsql.execdirect
query="select primary_type, count(*) as count from crimeCensus group by primary_type order by count desc";
quit;
1
DATA casuser.crimeCensus;
2
INFILEDATALINES dlm=';';
3
INPUT primary_type $ date :yymmdd10. community_area hardship_index per_capita_income;
4
FORMAT date yymmdd10.;
5
DATALINES;
6
THEFT;2015-01-15;10;80;25000
7
THEFT;2015-02-20;10;80;25000
8
THEFT;2015-03-01;10;80;25000
9
THEFT;2015-04-10;10;80;25000
10
THEFT;2015-05-05;10;80;25000
11
THEFT;2016-01-20;10;80;25000
12
THEFT;2016-02-25;10;80;25000
13
THEFT;2016-03-05;10;80;25000
14
THEFT;2016-04-15;10;80;25000
15
THEFT;2016-05-10;10;80;25000
16
ASSAULT;2015-01-01;20;70;30000
17
ASSAULT;2015-01-02;20;70;30000
18
ASSAULT;2015-01-03;20;70;30000
19
ASSAULT;2015-01-04;20;70;30000
20
ASSAULT;2015-01-05;20;70;30000
21
ROBBERY;2016-06-01;30;90;20000
22
ROBBERY;2016-06-02;30;90;20000
23
ROBBERY;2016-06-03;30;90;20000
24
ROBBERY;2016-06-04;30;90;20000
25
ROBBERY;2016-06-05;30;90;20000
26
;
27
RUN;
28
29
PROC CAS;
30
fedsql.execdirect
31
query="select primary_type, count(*) as count from crimeCensus group by primary_type order by count desc";
32
QUIT;
33
2 Bloc de code
FEDSQL.EXECDIRECT
Explication : Cet exemple reproduit le cas d'utilisation fourni dans la documentation. Il soumet une requête FedSQL plus complexe, filtrant par type de crime ('THEFT') et une plage de dates, regroupant par plusieurs variables et ayant une condition 'HAVING'. Le paramètre 'showStages=true' est activé pour obtenir le détail du plan d'exécution, montrant les différentes étapes du traitement de la requête sur le serveur CAS.
Copié !
proc cas;
fedsql.execdirect
showStages=true
query="select primary_type, count(*) as count, community_area,
hardship_index, per_capita_income from crimeCensus
where primary_type='THEFT'
and date between date '2015-01-01' and date'2016-01-01'
group by primary_type, community_area, hardship_index, per_capita_income
having count(*) >= 5
order by count desc";
quit;
1
PROC CAS;
2
fedsql.execdirect
3
showStages=true
4
query="select primary_type, count(*) as count, community_area,
5
hardship_index, per_capita_income from crimeCensus
6
where primary_type='THEFT'
7
and date between date '2015-01-01' and date'2016-01-01'
8
group by primary_type, community_area, hardship_index, per_capita_income
9
having count(*) >= 5
10
order by count desc";
11
QUIT;
3 Bloc de code
FEDSQL.EXECDIRECT
Explication : Cet exemple avancé introduit une jointure entre la table 'crimeCensus' (créée dans l'exemple 1) et une nouvelle table 'population_data'. La requête calcule le nombre total d'incidents et le taux d'incidents pour 1000 habitants pour des types de crimes spécifiques sur une période plus longue. L'utilisation de 'showStages=true' permet d'analyser le plan d'exécution pour cette requête multi-tables, y compris la façon dont la jointure et les calculs complexes sont gérés par FedSQL sur CAS.
Copié !
data casuser.population_data;
infile datalines dlm=';';
input community_area $ population;
datalines;
10;50000
20;75000
30;60000
;
run;
proc cas;
fedsql.execdirect
showStages=true
query="select c.primary_type, count(c.*) as total_incidents,
c.community_area, p.population,
(count(c.*) * 1000 / p.population) as incidents_per_1000
from crimeCensus as c
join population_data as p
on c.community_area = p.community_area
where c.primary_type in ('THEFT', 'ROBBERY')
and c.date between date '2015-01-01' and date '2016-12-31'
group by c.primary_type, c.community_area, p.population
having count(c.*) >= 2
order by incidents_per_1000 desc";
quit;
1
DATA casuser.population_data;
2
INFILEDATALINES dlm=';';
3
INPUT community_area $ population;
4
DATALINES;
5
10;50000
6
20;75000
7
30;60000
8
;
9
RUN;
10
11
PROC CAS;
12
fedsql.execdirect
13
showStages=true
14
query="select c.primary_type, count(c.*) as total_incidents,
15
c.community_area, p.population,
16
(count(c.*) * 1000 / p.population) as incidents_per_1000
17
from crimeCensus as c
18
join population_data as p
19
on c.community_area = p.community_area
20
where c.primary_type in ('THEFT', 'ROBBERY')
21
and c.date between date '2015-01-01' and date '2016-12-31'
22
group by c.primary_type, c.community_area, p.population
23
having count(c.*) >= 2
24
order by incidents_per_1000 desc";
25
QUIT;
4 Bloc de code
FEDSQL.EXECDIRECT / TABLE.REPLICATE
Explication : Cet exemple met l'accent sur l'intégration Viya/CAS en répliquant la table 'crimeCensus' (à des fins de démonstration, la table est d'abord recréée si nécessaire) dans la mémoire du serveur CAS à l'aide de l'action 'table.replicate'. La réplication peut améliorer les performances pour les petites tables accédées fréquemment. Ensuite, une requête FedSQL est exécutée sur la table répliquée avec 'showStages=true' pour observer comment le plan d'exécution tire parti de la table répliquée (par exemple, 'Replicated to one worker' dans la sortie du plan), ce qui peut montrer un temps d'accès aux données plus efficace.
Copié !
proc cas;
/* Créer la table crimeCensus si elle n'existe pas déjà (dupliqué pour l'autonomie) */
data casuser.crimeCensus;
infile datalines dlm=';';
input primary_type $ date :yymmdd10. community_area hardship_index per_capita_income;
format date yymmdd10.;
datalines;
THEFT;2015-01-15;10;80;25000
THEFT;2015-02-20;10;80;25000
THEFT;2015-03-01;10;80;25000
THEFT;2015-04-10;10;80;25000
THEFT;2015-05-05;10;80;25000
THEFT;2016-01-20;10;80;25000
THEFT;2016-02-25;10;80;25000
THEFT;2016-03-05;10;80;25000
THEFT;2016-04-15;10;80;25000
THEFT;2016-05-10;10;80;25000
ASSAULT;2015-01-01;20;70;30000
ASSAULT;2015-01-02;20;70;30000
ASSAULT;2015-01-03;20;70;30000
ASSAULT;2015-01-04;20;70;30000
ASSAULT;2015-01-05;20;70;30000
ROBBERY;2016-06-01;30;90;20000
ROBBERY;2016-06-02;30;90;20000
ROBBERY;2016-06-03;30;90;20000
ROBBERY;2016-06-04;30;90;20000
ROBBERY;2016-06-05;30;90;20000
;
run;
/* Répliquer la table crimeCensus dans CAS pour une meilleure performance */
table.replicate /
name='crimeCensus',
caslib='casuser',
target='crimeCensus_replicated',
numreplicas=1; /* Répliquer sur un seul worker pour une petite table */
/* Exécuter une requête FedSQL sur la table répliquée avec showStages */
fedsql.execdirect
showStages=true
query="select primary_type, count(*) as count from crimeCensus_replicated group by primary_type order by count desc";
quit;
1
PROC CAS;
2
/* Créer la table crimeCensus si elle n'existe pas déjà (dupliqué pour l'autonomie) */
3
DATA casuser.crimeCensus;
4
INFILEDATALINES dlm=';';
5
INPUT primary_type $ date :yymmdd10. community_area hardship_index per_capita_income;
6
FORMAT date yymmdd10.;
7
DATALINES;
8
THEFT;2015-01-15;10;80;25000
9
THEFT;2015-02-20;10;80;25000
10
THEFT;2015-03-01;10;80;25000
11
THEFT;2015-04-10;10;80;25000
12
THEFT;2015-05-05;10;80;25000
13
THEFT;2016-01-20;10;80;25000
14
THEFT;2016-02-25;10;80;25000
15
THEFT;2016-03-05;10;80;25000
16
THEFT;2016-04-15;10;80;25000
17
THEFT;2016-05-10;10;80;25000
18
ASSAULT;2015-01-01;20;70;30000
19
ASSAULT;2015-01-02;20;70;30000
20
ASSAULT;2015-01-03;20;70;30000
21
ASSAULT;2015-01-04;20;70;30000
22
ASSAULT;2015-01-05;20;70;30000
23
ROBBERY;2016-06-01;30;90;20000
24
ROBBERY;2016-06-02;30;90;20000
25
ROBBERY;2016-06-03;30;90;20000
26
ROBBERY;2016-06-04;30;90;20000
27
ROBBERY;2016-06-05;30;90;20000
28
;
29
RUN;
30
31
/* Répliquer la table crimeCensus dans CAS pour une meilleure performance */
32
TABLE.replicate /
33
name='crimeCensus',
34
caslib='casuser',
35
target='crimeCensus_replicated',
36
numreplicas=1; /* Répliquer sur un seul worker pour une petite table */
37
38
/* Exécuter une requête FedSQL sur la table répliquée avec showStages */
39
fedsql.execdirect
40
showStages=true
41
query="select primary_type, count(*) as count from crimeCensus_replicated group by primary_type order by count desc";
42
QUIT;
Ce matériel est fourni "tel quel" par We Are Cas. Il n'y a aucune garantie, expresse ou implicite, quant à la qualité marchande ou à l'adéquation à un usage particulier concernant le matériel ou le code contenu dans les présentes. We Are Cas n'est pas responsable des erreurs dans ce matériel tel qu'il existe maintenant ou existera, et We Are Cas ne fournit pas de support technique pour celui-ci.
« Soumettre une requête SQL à un système distribué comme CAS peut sembler simple, mais l'efficacité réelle dépend de la manière dont le moteur segmente le travail entre les nœuds. L'option showStages=true est votre meilleur allié pour l'optimisation.
Elle permet de visualiser si FedSQL effectue un 'Full Table Scan' coûteux ou s'il parvient à filtrer les données localement sur chaque worker avant de les regrouper. En analysant les 'stages', vous pouvez identifier des goulots d'étranglement, comme un tri massif qui sature le contrôleur, et ajuster votre code (par exemple, en indexant les colonnes de jointure ou en utilisant des tables répliquées) pour maximiser le parallélisme »
SAS et tous les autres noms de produits ou de services de SAS Institute Inc. sont des marques déposées ou des marques de commerce de SAS Institute Inc. aux États-Unis et dans d'autres pays. ® indique un enregistrement aux États-Unis. WeAreCAS est un site communautaire indépendant et n'est pas affilié à SAS Institute Inc.
Ce site utilise des cookies techniques et analytiques pour améliorer votre expérience.
En savoir plus.