MODIFICA: ecco un set di codice più completo che mostra esattamente cosa sta succedendo per la risposta seguente.Scrittura di query efficienti in SAS utilizzando Proc sql con Teradata
libname output '/data/files/jeff'
%let DateStart = '01Jan2013'd;
%let DateEnd = '01Jun2013'd;
proc sql;
CREATE TABLE output.id AS (
SELECT DISTINCT id
FROM mydb.sale_volume AS sv
WHERE sv.category IN ('a', 'b', 'c') AND
sv.trans_date BETWEEN &DateStart AND &DateEnd
)
CREATE TABLE output.sums AS (
SELECT id, SUM(sales)
FROM mydb.sale_volue AS sv
INNER JOIN output.id AS ids
ON ids.id = sv.id
WHERE sv.trans_date BETWEEN &DateStart AND &DateEnd
GROUP BY id
)
run;
L'obiettivo è semplicemente di interrogare la tabella per alcuni ID in base all'appartenenza alla categoria. Quindi riassumo l'attività di questi membri in tutte le categorie.
L'approccio di cui sopra è molto più lento di:
- Esecuzione della prima query per ottenere il sottoinsieme
- Esecuzione di una seconda query le somme ogni ID
- Esecuzione di una terza query che interno unisce le due risultato imposta.
Se sto capendo correttamente, potrebbe essere più efficiente assicurarsi che tutto il mio codice sia passato completamente attraverso il crossloading.
Dopo aver postato una domanda di ieri, un membro ha suggerito che potrei beneficiare di fare una domanda separata sulle prestazioni che è stato più specifico alla mia situazione.
Sto utilizzando SAS Enterprise Guide per scrivere alcuni programmi/query di dati. Non ho le autorizzazioni per modificare i dati sottostanti, che è memorizzato in 'Teradata'.
Il mio problema di base è scrivere query SQL efficienti in questo ambiente. Ad esempio, interrogo una tabella di grandi dimensioni (con decine di milioni di record) per un piccolo sottoinsieme di ID. Poi, io uso questo sottoinsieme di interrogare di nuovo il tavolo più grande:
proc sql;
CREATE TABLE subset AS (
SELECT
id
FROM
bigTable
WHERE
someValue = x AND
date BETWEEN a AND b
)
Questo funziona in una manciata di secondi e restituisce identità 90k di. Successivamente, voglio interrogare questo set di ID contro il grande tavolo, e ne conseguono problemi. Desidero sommare i valori nel tempo per gli ID:
proc sql;
CREATE TABLE subset_data AS (
SELECT
bigTable.id,
SUM(bigTable.value) AS total
FROM
bigTable
INNER JOIN subset
ON subset.id = bigTable.id
WHERE
bigTable.date BETWEEN a AND b
GROUP BY
bigTable.id
)
Per qualsiasi motivo, ciò richiede molto tempo. La differenza è che la prima query contrassegna "someValue". Il secondo riguarda tutte le attività, indipendentemente da ciò che è in 'someValue'. Ad esempio, potrei segnalare ogni cliente che ordina una pizza. Poi guarderei ogni acquisto per tutti i clienti che hanno ordinato la pizza.
Non ho molta familiarità con SAS, quindi sto cercando qualche consiglio su come farlo in modo più efficiente o accelerare le cose. Sono aperto a qualsiasi pensiero o suggerimento e per favore fatemi sapere se posso offrire maggiori dettagli. Immagino di essere sorpreso che la seconda query impieghi così tanto tempo per essere elaborata.
Ottima risposta. –
Questo è esattamente quello che stavo cercando. Grazie mille per l'informazione. Sto ancora imparando su SAS e Teradata perché sono nuovo ad entrambi, avendo fatto quasi tutto in R per ottenere un formato di database proprietario nel mio vecchio lavoro. Pubblicherò un esempio più completo del codice in una modifica alla mia domanda originale. Sono curioso di vedere cosa ne pensi. Cercherò anche di capire lo stato delle tabelle dei driver. Sembra che sarebbe una buona idea, specialmente i modi in cui ho bisogno di interrogare questi dati. Ancora una volta, grazie mille per il consiglio, lo apprezzo davvero e ne imparo. –
Jeff, la tua domanda aggiornata mostra che vuoi davvero utilizzare una query pass-through. Il modo in cui lo stai facendo ora garantisce che l'intera tabella deve essere scaricata da Teradata perché ti stai unendo a un set di dati SAS. Ti suggerisco di fare una nuova domanda poiché le risposte a questo sono diventate un po 'fuori dal campo di applicazione. Quando lo fai, vedi se riesci a trovare l'istruzione LIBNAME originale che definisce 'mydb'. – BellevueBob