I am using MySQL database with PHP's Yii Framework, It is an old version of MySQL, It can't be updated to latest one due to some reasons.
I have created this query to get Current month records of current year. This query was working fine on my local system, I have around 10,000 records, But when i made it to production server, it was also working fine but after 1 month, Records reach upto 1 million in that table, So query is taking more than 10 seconds, when there is huge traffic on the app, its makes the server slow, mysql is taking high CPU. But when records are less, The query is working fine, Otherwise query is taking so much time to return records, sometimes it takes like 25-26 seconds.
Here is my query
SELECT SUM(`coins`) as coins, subscription_id
FROM `user_rewards` `t`
WHERE YEAR(date_awarded) = YEAR(CURRENT_DATE)
AND MONTH(date_awarded) = MONTH(CURRENT_DATE)
GROUP BY subscription_id
ORDER BY coins DESC LIMIT 10
Is it possible to optimize this query more in a better way?
This is my user_rewards table
id, subscription_id, coins, date_awarded
A single subscription_id can have multiple records thats why I sum and do group by in my group...
Below is table schema.
CREATE TABLE `user_rewards` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`date_awarded` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`subscription_id` bigint(20) NOT NULL,
`coins` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `fk_sub_id` (`subscription_id`),
CONSTRAINT `fk_sub_id` FOREIGN KEY (`subscription_id`) REFERENCES `subscription_info` (`subscription_id`)
) ENGINE=InnoDB AUTO_INCREMENT=12907 DEFAULT CHARSET=latin1
SHOW CREATE TABLE user_rewards;
output, table statistic(total rows amount, approximate distinct subscription_id per output and average rows per month per subscription_id. Also - doesdate_awarded <= CURRENT_DATE
is true for ALL rows?user_rewards
ADD INDEXuser_rewards_ndx_date_awarded
(date_awarded
); ? If you do, B) Are you aware that in 2038, due to range limits, datatype of timestamp will begin failing sometime in January of 2038? Use of datetime time datatype would avoid the problem. If you can ADD INDEX for either datatype, I will prepare a query that will avoid current tablescan for you.