lesson 48 Advanced product analysis · advanced
Query plans & indexes
Inspect how SQLite reads data and uses indexes.
the idea
EXPLAIN QUERY PLAN describes how SQLite will read the data: SCAN reads a whole table, SEARCH uses an index to jump to matching rows, and a covering index answers from the index alone. A plan is evidence about access paths, not a timing measurement.
Dataset: Retail
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.
orders6 columns · 6,722 rows
| order_idnumber · unique id | invoice_notext | customer_idnumber · links to customers | ordered_atdate & time | countrytext | order_typetext |
|---|---|---|---|---|---|
| 1 | 489438 | 18102 | 2009-12-01 09:24:00 | United Kingdom | sale |
| 2 | 489517 | 16329 | 2009-12-01 11:34:00 | United Kingdom | sale |
| 3 | C489528 | 16714 | 2009-12-01 11:50:00 | United Kingdom | cancellation |
| 4 | 489529 | 17984 | 2009-12-01 11:51:00 | United Kingdom | sale |
| 5 | 489532 | 13394 | 2009-12-01 11:58:00 | United Kingdom | sale |
| 6 | 489540 | 12913 | 2009-12-01 12:18:00 | United Kingdom | sale |
- order_idnumber · unique id
- 1
- invoice_notext
- 489438
- customer_idnumber · links to customers
- 18102
- ordered_atdate & time
- 2009-12-01 09:24:00
- countrytext
- United Kingdom
- order_typetext
- sale
- order_idnumber · unique id
- 2
- invoice_notext
- 489517
- customer_idnumber · links to customers
- 16329
- ordered_atdate & time
- 2009-12-01 11:34:00
- countrytext
- United Kingdom
- order_typetext
- sale
- order_idnumber · unique id
- 3
- invoice_notext
- C489528
- customer_idnumber · links to customers
- 16714
- ordered_atdate & time
- 2009-12-01 11:50:00
- countrytext
- United Kingdom
- order_typetext
- cancellation
- order_idnumber · unique id
- 4
- invoice_notext
- 489529
- customer_idnumber · links to customers
- 17984
- ordered_atdate & time
- 2009-12-01 11:51:00
- countrytext
- United Kingdom
- order_typetext
- sale
- order_idnumber · unique id
- 5
- invoice_notext
- 489532
- customer_idnumber · links to customers
- 13394
- ordered_atdate & time
- 2009-12-01 11:58:00
- countrytext
- United Kingdom
- order_typetext
- sale
- order_idnumber · unique id
- 6
- invoice_notext
- 489540
- customer_idnumber · links to customers
- 12913
- ordered_atdate & time
- 2009-12-01 12:18:00
- countrytext
- United Kingdom
- order_typetext
- sale
first 6 of 6,722 rows · your queries use all of them
order_items7 columns · 125,613 rows
| order_item_idnumber · unique id | order_idnumber · links to orders | line_numbernumber | stock_codetext · links to products | descriptiontext | quantitynumber | unit_pricedecimal |
|---|---|---|---|---|---|---|
| 1 | 1 | 1 | 21329 | DINOSAURS WRITING SET | 28 | 0.98 |
| 2 | 1 | 2 | 21252 | SET OF MEADOW FLOWER STICKERS | 30 | 1.69 |
| 3 | 1 | 3 | 21100 | CHARLIE AND LOLA CHARLOTTE BAG | 30 | 1.15 |
| 4 | 1 | 4 | 21033 | JUMBO BAG CHARLIE AND LOLA TOYS | 30 | 2 |
| 5 | 1 | 5 | 20711 | JUMBO BAG TOYS | 60 | 1.3 |
| 6 | 1 | 6 | 21410 | COUNTRY COTTAGE DOORSTOP GREEN | 32 | 2.5 |
- order_item_idnumber · unique id
- 1
- order_idnumber · links to orders
- 1
- line_numbernumber
- 1
- stock_codetext · links to products
- 21329
- descriptiontext
- DINOSAURS WRITING SET
- quantitynumber
- 28
- unit_pricedecimal
- 0.98
- order_item_idnumber · unique id
- 2
- order_idnumber · links to orders
- 1
- line_numbernumber
- 2
- stock_codetext · links to products
- 21252
- descriptiontext
- SET OF MEADOW FLOWER STICKERS
- quantitynumber
- 30
- unit_pricedecimal
- 1.69
- order_item_idnumber · unique id
- 3
- order_idnumber · links to orders
- 1
- line_numbernumber
- 3
- stock_codetext · links to products
- 21100
- descriptiontext
- CHARLIE AND LOLA CHARLOTTE BAG
- quantitynumber
- 30
- unit_pricedecimal
- 1.15
- order_item_idnumber · unique id
- 4
- order_idnumber · links to orders
- 1
- line_numbernumber
- 4
- stock_codetext · links to products
- 21033
- descriptiontext
- JUMBO BAG CHARLIE AND LOLA TOYS
- quantitynumber
- 30
- unit_pricedecimal
- 2
- order_item_idnumber · unique id
- 5
- order_idnumber · links to orders
- 1
- line_numbernumber
- 5
- stock_codetext · links to products
- 20711
- descriptiontext
- JUMBO BAG TOYS
- quantitynumber
- 60
- unit_pricedecimal
- 1.3
- order_item_idnumber · unique id
- 6
- order_idnumber · links to orders
- 1
- line_numbernumber
- 6
- stock_codetext · links to products
- 21410
- descriptiontext
- COUNTRY COTTAGE DOORSTOP GREEN
- quantitynumber
- 32
- unit_pricedecimal
- 2.5
first 6 of 125,613 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.
Read the plan for customer_id. Run this. Explain shows SEARCH on an index—SQLite jumps to that customer’s rows instead of reading the whole orders table.
step-1.sqlEXPLAIN QUERY PLAN SELECT order_id FROM orders WHERE customer_id = 18102;
Read the plan for country. Run this. Without a helpful index on country, the plan shows SCAN and SQLite checks every order row.the pattern
example.sqlEXPLAIN QUERY PLAN SELECT order_id FROM orders WHERE country = 'Germany';
common mistake
An index on orders.customer_id helps a filter on customer_id; it does not help a filter on country.