首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >MySQL查询优化,非常慢

MySQL查询优化,非常慢
EN

Stack Overflow用户
提问于 2015-10-13 16:25:53
回答 1查看 102关注 0票数 1

这就是我想要实现的:

展示最后50名学生和他们最便宜的产品。

如果product不存在,则提供空值。

下面是SELECT查询:

代码语言:javascript
运行
复制
SELECT 
students.*,
cs.cheapest_id,
cs.cheapest_price
FROM students
LEFT JOIN (SELECT iqs.* FROM (
        SELECT 
        student_id,
        id AS cheapest_id,
        price AS cheapest_price
        FROM products
        ORDER BY price ASC
) AS iqs
GROUP BY iqs.student_id) AS cs ON cs.student_id = students.id
ORDER BY students.name DESC
LIMIT 50;

创建表:

代码语言:javascript
运行
复制
CREATE TABLE `students` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

INSERT INTO `students` VALUES ('1', 'Mark');
INSERT INTO `students` VALUES ('2', 'Chris');

CREATE TABLE `products` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `student_id` int(11) DEFAULT NULL,
  `price` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `student_id` (`student_id`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

INSERT INTO `products` VALUES ('1', '1', '2');
INSERT INTO `products` VALUES ('2', '1', '3');

结果:

代码语言:javascript
运行
复制
id  name    cheapest_id cheapest_price
1   Mark    1           2
2   Chris   (NULL)      (NULL)  

以下是问题所在:

如果两个表中都有许多记录,则查询速度非常慢(分钟)。

如果我使用INNER JOIN而不是LEFT JOIN,或者如果我删除了"ORDER BY students.name DESC“,那么查询速度会很快。

我已经在student_id上设置了索引,但它仍然非常慢。

有人能帮帮忙吗?我已经为此挣扎了好几天了.

编辑:解释的结果

代码语言:javascript
运行
复制
1   PRIMARY students    ALL 3   Using temporary; Using filesort
1   PRIMARY <derived2>  ALL 2   
2   DERIVED <derived3>  ALL 4   Using temporary; Using filesort 
3   DERIVED products    ALL 4   Using filesort
EN

回答 1

Stack Overflow用户

发布于 2015-10-13 16:43:09

尝试添加以下索引:

代码语言:javascript
运行
复制
ALTER TABLE `students` ADD INDEX (`id`, `name`);
ALTER TABLE `products` ADD INDEX (`student_id`, `id`, `price`);

并像这样编写您的查询:

代码语言:javascript
运行
复制
SELECT students.*,
   MIN(products.id) AS cheapest_id,
   MIN(products.price) AS cheapest_price

FROM students
LEFT JOIN products ON student_id = students.id

GROUP BY students.id
ORDER BY students.name DESC
LIMIT 50;

您应该明确地阅读有关EXPLAIN SELECT语法以及如何正确索引的信息:https://dev.mysql.com/doc/refman/5.6/en/explain.html https://dev.mysql.com/doc/refman/5.5/en/optimization-indexes.html

使用EXPLAIN SELET%您的查询%,您可以看到MySQL是如何优化查询的,以及引擎是如何实际读取您的数据集的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33097679

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档