简体   繁体   English

优化我的mysql查询以使用索引进行排序

[英]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. 我有一个基于3列的复合索引,其中两列在我的查询中受约束,第三列是按顺序子句,但mysql不使用索引进行排序。

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? 我该怎么做才能强制mysql使用索引来对结果进行排序?

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. 在这种情况下,MySQL优化器通常选择进行表扫描并完全忽略索引,因为它实际上比通过额外读取整个索引并使用它来挑选数据的麻烦更快。 So in this case, I'm guessing that public_private='yes' and approved='yes' matches a good portion of your table. 所以在这种情况下,我猜测public_private='yes' and approved='yes'匹配你桌子的很大一部分。 Therefore, if MySQL skips using the index because of this, then it's not available for sorting either. 因此,如果MySQL因此而跳过使用索引,那么它也不能用于排序。

If you really want it to use an index, then the solution would be to use FORCE INDEX : 如果你真的希望它使用索引,那么解决方案是使用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. 但是,我会运行一些测试来确保您获得的内容实际上比MySQL优化器选择的更快。 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: 如果您想使用approved_2密钥对number_of_views进行排序,请更改:

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. MySQL中的复合键从左到右工作。 In the above example, the key declared using number_of_views , approved , and public_private implicity creates indexes on: 在上面的示例中,使用number_of_viewsapprovedpublic_private implicity声明的键创建索引:

  • number_of_views
  • number_of_views , approved number_of_viewsapproved
  • number_of_views , approved , public_private number_of_viewsapprovedpublic_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 . 如果没有,只需在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.) (mysql基本上遵循左右序列。因此,如果未在此序列中使用,则您对approved public_privatenumber_of_views索引将不起作用。即,您可以使用左侧的所有三个,左侧的2个或最左侧的1.但它赢了如果你不使用最左边的那个就行了,那就是这个想法。)

Using a separate index would sort number_of_views automatically, this could help in order by -- this I am sure though. 使用单独的索引会自动对number_of_views进行排序,这可能有助于按order by - 但我确信这一点。

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. number_of_views列上添加单独的索引,然后查看它是否有效。

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 如果一个键是3列的组合,它将仅在使用全部3个键执行操作时才使用该特定键

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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