MySQL查询优化,速度很慢
这就是我想要实现的目标: 展示最后50名学生和他们最便宜的产品 如果产品不存在,则显示空值 以下是选择查询:MySQL查询优化,速度很慢,mysql,Mysql,这就是我想要实现的目标: 展示最后50名学生和他们最便宜的产品 如果产品不存在,则显示空值 以下是选择查询: 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
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;
创建表:
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');
结果:
id name cheapest_id cheapest_price
1 Mark 1 2
2 Chris (NULL) (NULL)
问题是:
如果两个表中都有许多记录,则查询速度非常慢(分钟)
如果我使用内部连接而不是左连接,或者如果我删除“ORDER BY students.name DESC”,查询速度很快
我已经在学生id上设置了索引,但仍然很慢
有人能帮忙吗?我已经为此挣扎了好几天
编辑:解释的结果
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
1名小学生全部3人临时使用;使用文件排序
1小学全部2
2.所有4项均使用临时性数据;使用文件排序
3个衍生产品全部4个使用filesort
尝试添加以下索引:
ALTER TABLE `students` ADD INDEX (`id`, `name`);
ALTER TABLE `products` ADD INDEX (`student_id`, `id`, `price`);
然后按如下方式编写查询:
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 SELET%YOUR QUERY%可以看到MySQL是如何优化查询的,以及引擎是如何实际读取数据集的
尝试添加以下索引:
ALTER TABLE `students` ADD INDEX (`id`, `name`);
ALTER TABLE `products` ADD INDEX (`student_id`, `id`, `price`);
然后按如下方式编写查询:
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 SELET%YOUR QUERY%可以看到MySQL是如何优化查询的,以及引擎是如何实际读取数据集的
1名小学生全部3名使用临时工;使用filesort 1 PRIMARY ALL 2派生所有4使用temporary;使用filesort 3派生产品所有4个使用filesort的产品在分组前都有ORDER BY,因为我不能在同一查询中分组和排序。ORDER BY必须发生在GROUP BY之前。不过,我总是忘记MySQL与ansi或其他DMB相比是自由的,当谈到GROUP by1小学生时,所有3个都使用临时数据库;使用filesort 1 PRIMARY ALL 2派生所有4使用temporary;使用filesort 3派生产品所有4个使用filesort的产品在分组前都有ORDER BY,因为我不能在同一查询中分组和排序。ORDER BY必须在GROUP BY之前进行。不过,我总是忘记MySQL在GROUP BY方面比ansi或其他DMB更自由。谢谢您的回答,我已经多次检查了EXPLAIN,但仍然找不到解决方案。您的SELECT查询也是错误的,因为它获取的是最小的产品id,而不是最便宜产品的id。这部分是错误的-MIN(products.id)作为最便宜的\u id。如果您使用您的查询,但使用我建议的索引?是的,我在原始表上的索引已经有10万条以上的记录,但仍然不起作用。我唯一没有索引的地方是id,因为它们已经是主键了。你们肯定需要正确的索引和优化的查询。我在示例表中没有看到这些索引。在explain select中显示了多少已检查的行?我已经按照您的建议在所有内容上添加了索引,但仍然很慢。以下是解释的屏幕截图:。我仍然在使用我的查询。谢谢你们的回答,我已经检查了多次解释,但仍然找不到解决这个问题的方法。您的SELECT查询也是错误的,因为它获取的是最小的产品id,而不是最便宜产品的id。这部分是错误的-MIN(products.id)作为最便宜的\u id。如果您使用您的查询,但使用我建议的索引?是的,我在原始表上的索引已经有10万条以上的记录,但仍然不起作用。我唯一没有索引的地方是id,因为它们已经是主键了。你们肯定需要正确的索引和优化的查询。我在示例表中没有看到这些索引。在explain select中显示了多少已检查的行?我已经按照您的建议在所有内容上添加了索引,但仍然很慢。以下是解释的屏幕截图:。我仍然在使用我的查询。