I have a single reporting table of sales data with about 4 million rows of data:
CREATE TABLE reporting_sales (
customer_id bigint(20) DEFAULT NULL,
effective_date date DEFAULT NULL,
expiration_date date DEFAULT NULL,
license_type_id int(11) DEFAULT NULL,
residency varchar(10) DEFAULT NULL,
gender varchar(10) DEFAULT NULL,
age_range varchar(10) DEFAULT NULL,
KEY ndx_reporting_sales (license_type_id,
effective_date,
expiration_date,
customer_id,
residency,
gender,
age_range) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
;
And this is the statement I want to run to summarize the data as of a particular day:
SELECT COUNT(DISTINCT customer_id),
license_type_id,
residency,
gender,
age_range
FROM tmp_reporting_sales_fl
WHERE license_type_id in (1, 2, 3, 4, 5)
AND effective_date <= '2021-01-01'
AND expiration_date >= '2021-01-01'
GROUP BY license_type_id, residency, gender, age_range
I'm not sure how the index should be structured, specifically with respect to the customer_id field and the grouping.
Here's the explain for the index I have created, as shown above:
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | reporting_sales | range | ndx_reporting_sales | ndx_reporting_sales | 4 | 1829784 | 16.66 | Using where; Using index; Using filesort |
How can I improve the performance of this statement and/or what would be a more suitable index?
(license_type_id, effective_date)
or(license_type_id, expiration_date)
(use those index which shows best selectivity, I predict that this will be the latter one). Anycase the rest of your index cannot work for shown query.PRIMARY KEY
?