Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用LIMIT MySQL时如何减少行查找_Mysql - Fatal编程技术网

使用LIMIT MySQL时如何减少行查找

使用LIMIT MySQL时如何减少行查找,mysql,Mysql,下表的索引位于id,外键位于activityID: 注释(id、活动id、文本) 以及以下查询: 从`comment`中选择,其中`comment`.`activityID`=1257按`id`顺序描述限制20; 我基本上只想获得该活动的前20条评论,共1165条,然而,这是一个描述的结果: id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE

下表的索引位于
id
,外键位于
activityID

注释(id、活动id、文本)

以及以下查询:

从`comment`中选择,其中`comment`.`activityID`=1257按`id`顺序描述限制20;
我基本上只想获得该活动的前20条评论,共1165条,然而,这是一个描述的结果:

id  select_type table   type    possible_keys   key         key_len ref     rows    Extra
1   SIMPLE      comment ref     activityID      activityID  4       const   1165    NULL
本质上,它是在决定限制此活动之前,先查看所有有关此活动的评论

我们在高负载下测试了这个查询,当一个活动有200000条注释时,查询需要5秒以上的时间,而在相同负载下,一个有30条注释的活动需要几毫秒的时间

PS:如果我删除
WHERE
子句,解释说它只会查找一行(不知道是否真的是这样):

有可能以任何方式优化这种查询吗


谢谢。

因为订货太慢了

查询使用
activityID
索引查找具有该ID的所有行。然后它必须读取所有200000条注释,并按
ID
对它们进行排序,以查找最后20条注释

添加复合索引,以便可以使用索引进行排序:

ALTER TABLE comment ADD INDEX (activityID, id);

请注意,
activityID
上的索引本身将不再需要,因为它是这个新索引的前缀。

排序导致了速度缓慢

查询使用
activityID
索引查找具有该ID的所有行。然后它必须读取所有200000条注释,并按
ID
对它们进行排序,以查找最后20条注释

添加复合索引,以便可以使用索引进行排序:

ALTER TABLE comment ADD INDEX (activityID, id);
请注意,
activityID
上的索引本身将不再需要,因为它是这个新索引的前缀。

使用偏移量

SELECT <cols> FROM `comment` WHERE `comment`.`activityID` = 1257 ORDER BY `id` DESC LIMIT 0,20;
从`comment`中选择,其中`comment`.`activityID`=1257按`id`DESC限制0,20排序;
在limit子句中,添加
0
作为偏移量,以仅获取前20条注释使用偏移量

SELECT <cols> FROM `comment` WHERE `comment`.`activityID` = 1257 ORDER BY `id` DESC LIMIT 0,20;
从`comment`中选择,其中`comment`.`activityID`=1257按`id`DESC限制0,20排序;

在limit子句中,添加
0
作为偏移量,只需在
activityID
id
上添加两个单独的索引即可。这也将有助于您按排序。优化中没有硬性规定,但您需要尝试各种方法

这样做:

ALTER TABLE comment ADD INDEX (id);
ALTER TABLE comment ADD INDEX (activityID);

我想这会有帮助。

只需在
activityID
id
上添加两个单独的索引即可。这也将有助于您按排序。优化中没有硬性规定,但您需要尝试各种方法

这样做:

ALTER TABLE comment ADD INDEX (id);
ALTER TABLE comment ADD INDEX (activityID);


我想这会有帮助。

如果添加一个
ORDER BY
子句,会发生什么?没有ORDER BY的LIMIT通常是一种代码味道,因为您不知道将得到哪个20。实际上,我们使用的查询有一个
ORDER BY id DESC
子句。我会更新的。可能没什么大不了的,在选择的帮助下会更具体<代码>从中选择'text',而不是
*
?实际的代码选择特定的列,我只是将其剥离以使其更易于阅读,并且不会产生任何差异。如果添加一个
ORDER BY
子句,会发生什么?没有ORDER BY的LIMIT通常是一种代码味道,因为您不知道将得到哪个20。实际上,我们使用的查询有一个
ORDER BY id DESC
子句。我会更新的。可能没什么大不了的,在选择的帮助下会更具体<代码>从中选择'text',而不是*?实际的代码选择特定的列,我只是将其剥离以使其更易于阅读,它不会有任何区别。它没有任何区别。尝试不进行任何排序,尝试使用您建议的索引按id排序,
EXPLAIN
返回完全相同的结果。即使删除了旧索引,也可以使用外键。因为它是这个新键的前缀,所以它仍然可以用作外键。我的观点是,
orderby
没有任何区别,我甚至尝试使用
强制索引(
activityID\u id
),它是一样的。它没有任何区别。尝试不进行任何排序,尝试使用您建议的索引按id排序,
EXPLAIN
返回完全相同的结果。即使删除了旧索引,也可以使用外键。因为它是这个新键的前缀,所以它仍然可以用作外键。我的观点是,
ORDER BY
没有任何区别,我甚至尝试使用
强制索引(
activityID\u id
),它是相同的。但是如果没有提供偏移,偏移的默认值是零,所以这似乎没有改变任何东西?哦,对不起,我弄错了,但是如果没有提供偏移量,偏移量的默认值是零,所以这似乎没有改变任何东西?哦,对不起,我的错误
id
默认情况下总是有索引
activityID
是外键。我不知道你为什么否决了我的答案,你没有在任何地方写下你的
id
是问题的主键。这就是为什么我写信来确认这一点。无论如何,如果
id
是主键,您仍然需要在
activityID
上创建索引。因为外键不会在MyIsam引擎中自动索引,而只在InnoDB中。另外,这是SQL查询将遍历所有记录的一般经验法则,这些记录是满足索引条件的一部分。如果您想进一步减少结果,您需要使用一些组合键来减少行数。
id
默认情况下始终有一个索引
activityID
是外键。我不知道你为什么否决了我的答案,你没有在任何地方写下你的
id
是问题的主键。这就是我为什么这么想的原因