Search code examples
mysqlsqloptimizationdatabase-indexesfilesort

Mysql query with inner subquery and where,order,group not use indexes


all. I have 2 mysql tables type myisam

CREATE TABLE `users` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

CREATE TABLE `users_ratings` (
  `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
  `created_date` varchar(255) DEFAULT NULL,
  `user_id` mediumint(9) DEFAULT NULL,
  `rating1` mediumint(9) DEFAULT NULL,
  `rating2` mediumint(9) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

Dump can be downloaded here

I want all users to select and sort the list by rating2 and rating2 must be > 1000

SELECT * FROM users as u 
INNER JOIN (SELECT rating2, user_id,MAX(created_date) as maxdate FROM `users_ratings` GROUP BY user_id) as x ON x.user_id = u.id 
INNER JOIN users_ratings as ur ON(ur.created_date = x.maxdate and ur.user_id = u.id) 
WHERE x.rating2 > 1000 
ORDER by ur.rating2

Without such an index the query is executed for 9 seconds.

All possible codes, which I thought was allowed to reduce the time of the request to 1-2 seconds.

Help the right to place indexes


Solution

  • I suspect you want the following query. Assuming you do, and performance is still an issue, provide the EXPLAIN for same...

    (this assumes a Unique Key on user_id,[rating2,]created_date, which hasn't actually been specified)

    SELECT u.*
         , x.*
      FROM users u 
      JOIN users_ratings x
        ON x.user_id = u.id
      JOIN 
         ( SELECT user_id
                , MAX(created_date) maxdate 
             FROM users_ratings
            WHERE rating2 > 1000
            GROUP 
               BY user_id
         ) y 
        ON y.user_id = x.user_id 
       AND y.maxdate = x.created_date
     ORDER 
        BY x.rating2;