For the query above, the following recommendations will be helpful as part of the SQL tuning process.
You'll find 3 sections below:
The optimization process and recommendations:
- Avoid Calling Functions With Indexed Columns (query line: 18): When a function is used directly on an indexed column, the database's optimizer won’t be able to use the index. For example, if the column `date` is indexed, the index won’t be used as it’s wrapped with the function `MONTH`. If you can’t find an alternative condition that won’t use a function call, a possible solution is to store the required value in a new indexed column.
- Avoid Calling Functions With Indexed Columns (query line: 19): When a function is used directly on an indexed column, the database's optimizer won’t be able to use the index. For example, if the column `date` is indexed, the index won’t be used as it’s wrapped with the function `YEAR`. If you can’t find an alternative condition that won’t use a function call, a possible solution is to store the required value in a new indexed column.
- Explicitly ORDER BY After GROUP BY (modified query below): By default, the database sorts all 'GROUP BY col1, col2, ...' queries as if you specified 'ORDER BY col1, col2, ...' in the query as well. If a query includes a GROUP BY clause but you want to avoid the overhead of sorting the result, you can suppress sorting by specifying 'ORDER BY NULL'.
The optimized query:
SELECT
DATE_FORMAT(`date`,
"%Y-%m-01 00:00:00") AS `date`,
aggregate_data.offer_id,
aggregate_data.country,
@sum_impressions := SUM(aggregate_data.impressions),
@sum_clicks := SUM(aggregate_data.clicks),
@sum_leads := SUM(aggregate_data.leads),
@sum_payout := SUM(aggregate_data.payout),
@sum_revenue := SUM(aggregate_data.revenue)
FROM
aggregate_data
WHERE
`date` >= '2012-12-00 00:00:00'
GROUP BY
aggregate_data.country,
aggregate_data.offer_id,
MONTH(`date`),
YEAR(`date`)
ORDER BY
NULL