Put the data in folders named after the thing you filter on, so most queries never open most folders.
Filing invoices in one folder per month. Asked for August, you open one folder. Inside it, keeping them in customer order means you can find one without reading all of them.
On a pay-per-byte warehouse, one partition filter is routinely a 99% cost reduction — and one careless function call removes it.
Partitioning splits a table into physically separate chunks by the value of a column — almost always a date. A query filtered to one week then opens seven directories instead of five years of them, and the bytes it never reads are bytes you never pay for. Clustering (or Z-ordering, or sorting) works inside those chunks: it orders rows so that the min/max statistics of each file are narrow, letting the engine skip files a partition filter alone couldn't. The two are complementary and both fail the same way — pick a column with too many distinct values and you get a million tiny partitions, which is slower than no partitioning at all.
Partitioning physically separates rows by a column value, usually a date, so a filtered query prunes whole directories before reading anything. Clustering sorts rows within each partition so per-file min/max statistics are tight and the engine can skip individual files too. Partition on a low-cardinality column you almost always filter on; cluster on the high-cardinality ones you filter on sometimes.
How does BigQuery store data? — Google Cloud Tech, 8:20