简体   繁体   中英

Optimizing my mysql query to use index for sorting

I have a composite index based on 3 columns, two of which are constrained in my query and the 3rd is in order by clause yet mysql doesn't use index for sorting.

explain select * from videos where public_private='public' and approved='yes' order by number_of_views desc;

+----+-------------+--------+------+--------------------------------+------+---------+------+---------+-----------------------------+
| id | select_type | table  | type | possible_keys                  | key  | key_len | ref  | rows    | Extra     |
+----+-------------+--------+------+--------------------------------+------+---------+------+---------+-----------------------------+
|  1 | SIMPLE      | videos | ALL  | approved,approved_3,approved_2 | NULL | NULL    | NULL | 1476818 | Using where; Using filesort |
+----+-------------+--------+------+--------------------------------+------+---------+------+---------+-----------------------------+

The table structure is as follows:

CREATE TABLE `videos` (
  `indexer` int(9) NOT NULL auto_increment,
  `user_id` int(9) default NULL,
  `public_private` varchar(24) default NULL,
  `approved` varchar(24) default NULL,
  `number_of_views` int(9) default NULL,
  PRIMARY KEY  (`indexer`),
  KEY `approved` (`approved`,`user_id`),
  KEY `approved_3` (`approved`,`public_private`,`indexer`),
  KEY `approved_2` (`approved`,`public_private`,`number_of_views`),
) ENGINE=MyISAM AUTO_INCREMENT=1969091 DEFAULT CHARSET=utf8 |

What should I do to force mysql to use index for sorting the results?

I believe that the query you have is probably matching a large percentage of the data in the table. In situations such as this, the MySQL optimizer often chooses to do a table scan and ignore indexes completely, as it is actually faster than going through the trouble of the additional reading of the entire index and using it to pick out the data. So in this case, I'm guessing that public_private='yes' and approved='yes' matches a good portion of your table. Therefore, if MySQL skips using the index because of this, then it's not available for sorting either.

If you really want it to use an index, then the solution would be to use FORCE INDEX :

select * from videos FORCE INDEX (approved_2) where public_private='public' and approved='yes' order by number_of_views desc;

However, I would run some tests to make sure that what you're getting is actually faster than what the MySQL optimizer has chosen to do. Apparently the optimizer does have some issues with making selections for ordering, so you could definitely give this a shot and see if you get improved performance.

The order does matter in composite keys. If you want to sort by just number_of_views using the approved_2 key, Change:

KEY `approved_2` (`approved`,`public_private`,`number_of_views`)

to:

KEY `approved_2` (`number_of_views`,`approved`,`public_private`)

Composite keys in MySQL work left-to-right. In the above example, the key declared using number_of_views , approved , and public_private implicity creates indexes on:

  • number_of_views
  • number_of_views , approved
  • number_of_views , approved , public_private

This should work:

`select * from videos where approved='yes' and public_private='public' order by number_of_views desc;` 

Tf it does not, just create a separate index on number_of_views .

This must work.

(mysql follows left-right sequence basically. So your index on approved , public_private , number_of_views will not work if not used in this sequence. ie, you can use all three from left, 2 from left or the left most 1. But it won't work if you dont use the leftmost one, that's the idea.)

Using a separate index would sort number_of_views automatically, this could help in order by -- this I am sure though.

The order matters in composite keys. I forget the rules, but try in a different order.

add a separate index on the number_of_views column and see if it works then.

If a key is a combination of 3 columns, it will use that particular key only when it is using all 3 to perform an operation

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM