Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/70.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.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 - Fatal编程技术网

MySQL查询优化,速度很慢

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

这就是我想要实现的目标:

展示最后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
        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中显示了多少已检查的行?我已经按照您的建议在所有内容上添加了索引,但仍然很慢。以下是解释的屏幕截图:。我仍然在使用我的查询。