Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.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
MySQl查询:加入并分组,性能较慢_Mysql_Performance - Fatal编程技术网

MySQl查询:加入并分组,性能较慢

MySQl查询:加入并分组,性能较慢,mysql,performance,Mysql,Performance,我有一个MySQL查询的问题,我不能优化它 SELECT p.id, p.name, p.sku, p.type FROM xm_products p LEFT JOIN xm_store_product sp ON p.id = sp.product_id LEFT JOIN xm_store s ON sp.store_id = s.id WHERE s.id = 1 ORDER BY p.type, p.name asc LI

我有一个MySQL查询的问题,我不能优化它

SELECT 
  p.id, 
  p.name,
  p.sku, 
  p.type
FROM 
  xm_products p 
  LEFT JOIN xm_store_product sp ON p.id = sp.product_id 
  LEFT JOIN xm_store s ON sp.store_id = s.id 
WHERE 
  s.id = 1 
ORDER BY 
  p.type, 
  p.name asc 
LIMIT 
  20 OFFSET 0
这个查询非常慢:Querytime 2.532s

如果删除ORDERBY子句,查询速度会非常快:0.0001s

解释并显示以下信息:

+----+-------------+-------+--------+-------------------------------------------+----------------------+---------+---------------------------------------+--------+----------------------------------------------+
| id | select_type | table | type   | possible_keys                             | key                  | key_len | ref                                   | rows   | Extra                                        |
+----+-------------+-------+--------+-------------------------------------------+----------------------+---------+---------------------------------------+--------+----------------------------------------------+
|  1 | SIMPLE      | s     | const  | PRIMARY                                   | PRIMARY              | 4       | const                                 |      1 | Using index; Using temporary; Using filesort |
|  1 | SIMPLE      | sp    | ref    | IDX_CA42254AB092A811,IDX_CA42254A4584665A | IDX_CA42254AB092A811 | 5       | const                                 | 102157 | Using where                                  |
|  1 | SIMPLE      | p     | eq_ref | PRIMARY                                   | PRIMARY              | 4       | model.sp.product_id                   |      1 |                                              |
+----+-------------+-------+--------+-------------------------------------------+----------------------+---------+---------------------------------------+--------+----------------------------------------------+
3 rows in set
我有三张桌子:

  • 具有主键id的xm_产品
  • 具有主键id的xm_存储
  • xm_store_product,索引为store_id和product_id
我尝试在p.name和p.type上添加一个索引,以及一个组合索引(p.name,p.type),但没有帮助

如何优化此查询的性能

编辑:

我花了2个小时创建了一个sqlfidle。但这里有一些数据。

问题是“分组方式”导致“使用索引;使用临时;使用文件排序”

我如何纠正我的例子

编辑2:


De xm_products表有大约20万条记录。xm_store_的产品约为40万件。该查询是针对寻呼机的,每页限制为20个。

我会在正面反馈后将其作为答案:)

性能上存在(明显的)差异是很有道理的

我不知道你们的桌子有多大,但限制20只会在没有订单的情况下提高性能。 使用order by时,必须首先检索所有记录,然后才能执行order by,而如果没有order by,则在20次匹配后停止执行


也许在order by子句上有一个组合索引,并且有一个视图可以提高性能。

您的问题是MySQL优化器是基于成本的

因此,它计算出访问表的最佳计划。在这种情况下,MySQL选择了错误的顺序。。因为基于等待时间,磁盘i/o比CPU周期更昂贵

您根据表产品(p.type,p.name asc)进行排序,但此表是在解释计划中最后访问的,因此MySQL需要“使用临时”构建一个临时表来保存结果。。由于结果没有正确排序,因此需要额外的快速排序“使用文件排序”

您可以使用STRAIGHT_JOIN进行测试,以便“绕过”MySQL优化器。注意,如果表中不存在s.id=1,则可能会产生负面性能结果

SELECT 
  STRAIGHT_JOIN
  p.id, 
  p.name,
  p.sku, 
  p.type
FROM 
  xm_products p 
  LEFT JOIN xm_store_product sp ON p.id = sp.product_id 
  LEFT JOIN xm_store s ON sp.store_id = s.id 
WHERE 
  s.id = 1 
ORDER BY 
  p.type, 
  p.name asc 
LIMIT 
  20 OFFSET 0

注意,如果您还共享create table语句输出,则可能会有更好的选项请参阅。。。如果s.id始终为1条记录,您可以使用派生表方法注意:您可能需要添加一个新索引

Hi您可以使用示例值为您的模式创建一个sqlfiddle(sqlfiddle.com)链接吗?您是否使用p.name和p.type上的索引运行了解释?它需要排序多少条记录?是否存在一个(可注意的)性能上的差异很有意义。我不知道你们的桌子有多大,但限制20只会在没有订单的情况下提高性能。使用order by时,必须首先检索所有记录,然后才能执行order by,而如果没有order by,则在20次匹配后停止执行。也许在你的order by子句上有一个组合索引,并且有一个关于你可以获得性能的视图。@oerkelens-你完全正确,我认为你的评论应该是一个答案。限制20是存在的,因为查询是针对寻呼机的。我不认为它对性能有影响不,它没有。但是如果没有order by,LIMIT会对性能产生影响,这是一个积极的影响,这就是为什么该版本要快得多。好了,现在我明白了。这意味着,我必须在其他地方搜索问题。