0

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
3
  • 1
    Provide complete 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 - does date_awarded <= CURRENT_DATE is true for ALL rows?
    – Akina
    Commented Nov 17, 2020 at 17:52
  • Do you have flexibility (data space availability) to A) USE (yourDB); and ALTER TABLE user_rewards ADD INDEX user_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. Commented Nov 21, 2020 at 13:53
  • If any of the comments or Answers helped you, please upvote or Accept so we know you are making progress, please and Thank You. Commented Nov 28, 2020 at 15:51

1 Answer 1

1

First visible improvement (assuming that there is no date_awarded values in future) is

WHERE date_awarded >= DATE_FORMAT(CURRENT_DATE, '%Y-%m-01')

Second - the index by (subscription_id, date_awarded, coins) (or maybe (date_awarded, subscription_id, coins), depends on table statistic, must be tested).

6
  • 1
    I have added show create table scheme in questions, kindly check. Date_awarded is always there, its never null Commented Nov 17, 2020 at 18:02
  • 1
    there can be average of 40 rows per subscription_id, we have total of 153,000 subscription_id, and its increasing day by day. Commented Nov 17, 2020 at 18:05
  • @AsfandyarKhan If so then both tips are relevant. And I do not see the base for third tip (it could be "drop id and use natural PK" but I doubt in such tips)..
    – Akina
    Commented Nov 17, 2020 at 18:53
  • @Akina Are you aware the datatype of date_awarded is timestamp rather than datetime datatype in the SHOW CREATE TABLE output? Not sure how your WHERE solution can be effective. Commented Nov 21, 2020 at 21:31
  • 1
    @WilsonHauck The difference between TIMESTAMP and DATETIME in MySQL is that TIMESTAMP data is adjusted with timezone during save/retrieve whereas for DATETIME the timezone is ignored. But in the storage or during query processing both datatypes are stored/processed as GMT data - so none problems occures. PS. Taking into account the meaning of a column I think that TIMESTAMP datatype was wrong selection...
    – Akina
    Commented Nov 21, 2020 at 22:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.