Working Efficiently with Large Data
Prerequisites: BY-group processing
SAS processes tables from disk, so it handles data far larger than memory — but the way you write a step decides whether it takes seconds or hours.
Read less
- Filter early with WHERE —
set big(where=(year = 2024));skips rows before they reach the step; a subsettingIFreads them all first. - Keep only the columns you need —
set big(keep=id year amount);reads less from disk. - Don't copy data needlessly — a DATA step that only renames or
relabels rewrites the whole table;
PROC DATASETSwithmodifychanges attributes in place.
Turn on options fullstimer; to see real time, CPU time, and memory for
every step in the log.
Indexes
An index speeds up WHERE queries that select a small fraction of
rows, and lets BY work without sorting:
/* illustrative */
proc datasets library=mydata nolist;
modify transactions;
index create customer_id;
quit;
Indexes help when a query selects a few percent of rows or less; for queries that read most rows, a sequential scan is faster.
Hash objects: lookups without sorting
A hash object loads a small table into memory for instant key
lookups — a fast alternative to sorting both tables and merging. Using
customers and orders from Level 2:
data orders_named;
if 0 then set customers;
if _n_ = 1 then do;
declare hash h(dataset: 'customers');
h.defineKey('id');
h.defineData('name');
h.defineDone();
end;
set orders;
if h.find() ne 0 then name = '';
run;
proc print data=orders_named noobs;
run;
id name amount
1 Ada 50
1 Ada 20
3 Grace 75
4 10
if 0 then set customers;never executes, but at compile time it addsidandnameto the PDV with the right types and lengths.declare hashruns once (_n_ = 1) and loadscustomersinto memory.h.find()looks up the currentid; it returns 0 when found and copiesnameinto the PDV.- Variables that come from a
SETdata set are retained, so on a failed lookupnamewould keep the previous row's value — hence the explicitname = ''.
Neither table needs sorting, and the large table is read only once. Hash objects also support iteration, counting, and de-duplication.
Other techniques
- Compression —
options compress=yes;shrinks tables with long character variables, trading CPU for disk I/O. - Database pass-through — with data in Oracle, SQL Server, Snowflake,
and so on, let the database do the filtering and joining. SAS
translates simple
WHEREclauses automatically; explicit pass-through (connect to ... ; select * from connection to ...) sends native SQL. - Avoid repeated sorts — sort once and keep the sorted copy, or use
CLASSinstead ofBYin procedures. - Views —
data v / view=v;orcreate viewdefine a query that runs only when read, saving a copy of the data.