runtime
69 / 88

lesson 69 Performance & query plans · advanced

Partitioning & workload trade-offs

Reason about partitioning choices for different workloads.

the idea

Partitioning splits a large table by a key, typically time, so queries that filter on that key read only matching partitions, and old data can be dropped as whole partitions. Its value depends on queries filtering by the partition key. SQLite has no native partitioning; you can still write the aligned range filters and per-period summaries partitioned engines reward.

Dataset: Energy

The tables the challenges use, with their first 6 rows. Under each column name: the kind of value it holds, and which table it links to.

hourly_demand9 columns · 52,405 rows
ba_codetext · links to balancing_authoritieshour_ending_utcdate & time · unique idhour_ending_localdate & timedemand_mwnumberforecast_mwnumberlocal_datedate · links to calendarhour_numbernumberadjusted_demand_mwnumberdemand_imputednumber
BPAT2024-01-01 09:002024-01-01 01:00630263092024-01-01163020
BPAT2024-01-01 10:002024-01-01 02:00623062362024-01-01262300
BPAT2024-01-01 11:002024-01-01 03:00617962652024-01-01361790
BPAT2024-01-01 12:002024-01-01 04:00619762772024-01-01461970
BPAT2024-01-01 13:002024-01-01 05:00637863942024-01-01563780
BPAT2024-01-01 14:002024-01-01 06:00660766252024-01-01666070
ba_codetext · links to balancing_authorities
BPAT
hour_ending_utcdate & time · unique id
2024-01-01 09:00
hour_ending_localdate & time
2024-01-01 01:00
demand_mwnumber
6302
forecast_mwnumber
6309
local_datedate · links to calendar
2024-01-01
hour_numbernumber
1
adjusted_demand_mwnumber
6302
demand_imputednumber
0
ba_codetext · links to balancing_authorities
BPAT
hour_ending_utcdate & time · unique id
2024-01-01 10:00
hour_ending_localdate & time
2024-01-01 02:00
demand_mwnumber
6230
forecast_mwnumber
6236
local_datedate · links to calendar
2024-01-01
hour_numbernumber
2
adjusted_demand_mwnumber
6230
demand_imputednumber
0
ba_codetext · links to balancing_authorities
BPAT
hour_ending_utcdate & time · unique id
2024-01-01 11:00
hour_ending_localdate & time
2024-01-01 03:00
demand_mwnumber
6179
forecast_mwnumber
6265
local_datedate · links to calendar
2024-01-01
hour_numbernumber
3
adjusted_demand_mwnumber
6179
demand_imputednumber
0
ba_codetext · links to balancing_authorities
BPAT
hour_ending_utcdate & time · unique id
2024-01-01 12:00
hour_ending_localdate & time
2024-01-01 04:00
demand_mwnumber
6197
forecast_mwnumber
6277
local_datedate · links to calendar
2024-01-01
hour_numbernumber
4
adjusted_demand_mwnumber
6197
demand_imputednumber
0
ba_codetext · links to balancing_authorities
BPAT
hour_ending_utcdate & time · unique id
2024-01-01 13:00
hour_ending_localdate & time
2024-01-01 05:00
demand_mwnumber
6378
forecast_mwnumber
6394
local_datedate · links to calendar
2024-01-01
hour_numbernumber
5
adjusted_demand_mwnumber
6378
demand_imputednumber
0
ba_codetext · links to balancing_authorities
BPAT
hour_ending_utcdate & time · unique id
2024-01-01 14:00
hour_ending_localdate & time
2024-01-01 06:00
demand_mwnumber
6607
forecast_mwnumber
6625
local_datedate · links to calendar
2024-01-01
hour_numbernumber
6
adjusted_demand_mwnumber
6607
demand_imputednumber
0

first 6 of 52,405 rows · your queries use all of them

worked example

Run these steps in order to see the idea before you write your own query. The step marked “the pattern” is what the challenges ask for. Running the example does not count toward progress.

  1. Count rows per month slice. Grouping hour_ending_utc by month shows how a time-partitioned table would be split—each month is one logical partition of the hourly data.the pattern

    example.sql
    SELECT
      substr(hour_ending_utc, 1, 7) AS month,
      COUNT(*) AS rows_in_partition
    FROM hourly_demand
    GROUP BY month;
  2. Filter one authority and one month. PJM demand for March 2024 with a half-open range on hour_ending_utc matches how partitioned engines read only the partitions you need.

    step-2.sql
    SELECT COUNT(*) AS hours
    FROM hourly_demand
    WHERE ba_code = 'PJM'
      AND hour_ending_utc >= '2024-03-01'
      AND hour_ending_utc < '2024-04-01';

common mistake

A filtered result in SQLite is not evidence of partition elimination. Queries that do not filter on the partition key read every partition.

challenge 1

Return ba_code, hour_ending_utc and demand_mw for ERCO in January 2024 using a half-open range on hour_ending_utc (the partition key).

what to return

Columns
ba_codehour_ending_utcdemand_mw in this order
Rows
any order
challenge-1.sql
 
To master this lesson, solve both challenges without hints and pass the concept check. 3 of 3 to go.
Partitioning & workload trade-offs — Performance & query plans · Runtime