Mysql 优化子查询和排序

Mysql 优化子查询和排序,mysql,indexing,query-optimization,Mysql,Indexing,Query Optimization,有没有一种方法可以在mysql中为下面的查询设置一个不使用任何文件排序的索引 SELECT * FROM bigtable WHERE id IN ([a indexed subquery]) ORDER BY title; 本例中的ID是主键。使用Innodb。 对这种查询进行解释时,总是会说它使用了filesort 编辑1: 子查询并不重要,因为在我的例子中它是自动生成的。 但是为了便于讨论,让我们改为这样进行查询 SELECT * FROM bigtable WHERE id IN (4

有没有一种方法可以在mysql中为下面的查询设置一个不使用任何文件排序的索引

SELECT * FROM bigtable WHERE id IN ([a indexed subquery]) ORDER BY title;
本例中的ID是主键。使用Innodb。 对这种查询进行解释时,总是会说它使用了filesort

编辑1:

子查询并不重要,因为在我的例子中它是自动生成的。 但是为了便于讨论,让我们改为这样进行查询

SELECT * FROM bigtable WHERE id IN (4,6,8,7,10,40,21,54...) ORDER BY title; 
是否有任何方法可以为不使用“ORDER BY”文件排序的查询编制索引


附加问题:还有其他数据库可以这样做吗?

您是否有权限在数据库(或托管在同一mysql服务器上的任何其他数据库)中创建临时表

如果是,那么我提出以下解决方案:

CREATE TEMPORARY TABLE temp_indexed_subquery
SELECT id 
FROM bigtable 
WHERE "where conditions";
SELECT b.* FROM bigtable AS b
JOIN temp_indexed_subquery AS t 
ON t.id = b.id;
CREATE TEMPORARY TABLE temp_indexed_subquery
(UNIQUE KEY id(id), KEY title(title)) 
SELECT id, title
FROM bigtable 
WHERE "where conditions";
SELECT b.*, t.title FROM temp_indexed_subquery AS t
JOIN bigtable AS b
ON b.id = t.id
ORDER BY t.title;
如果没有,请尝试以下操作:

SELECT b.* 
FROM bigtable 
JOIN (SELECT id FROM bigtable WHERE "where conditions") t ON t.id = b.id;
如果不知道表结构或子查询,就很难提供更多帮助

编辑:啊,我在filesort中遇到了类似的问题,并通过以下方式解决了它(修改了第一个建议的解决方案):

在这里,我在临时表的“title”字段上添加了一个索引,并根据该索引进行排序。在我的例子中,这样做意味着MySQL不必使用filesort来给我一个有序的结果。我希望这有帮助。
(顺便问一下,bigtable有多少行,以及索引子查询中通常有多少ID)

在某些情况下,MySQL将使用索引进行排序。如果在
bigtable(title)
上有索引,则以下查询应使用该索引:

select *
from bigtable
order by title;

我希望您的查询也使用索引,除非“索引子查询”导致优化器向我们提供不同的执行计划。MySQL在按顺序排序的优化策略方面做得相当好,在这里进行文件排序操作真的这么糟糕吗?从我得到的,例如,它可能被称为文件排序,但本质上它只是一个普通的排序;您在您的
订单中明确要求的

我假设系统使用
id
字段上的索引来查找相关记录,这些记录根据定义存储在
id
顺序中,从找到的记录中提取标题值,然后对结果进行排序,然后将其返回给客户机


我想不出一个好办法来避免这种情况,也不知道为什么这会很糟糕。如果您真的、真的、真的想,您可以尝试以某种方式将PK更改为
标题
+
ID
字段,然后让查询扫描整个表,以找到正确的
ID
。但这将是非常低效的,并且只能(潜在地)使用单线程。一旦它在多个线程上爆发,您仍然需要累积结果并对结果进行排序,以确保输出。考虑到可能有一些优化会“破坏”天真的“从头到尾扫描”方法,即使在最好的情况下,系统也会以安全的方式进行排序,我也不会太惊讶。

做了大量研究,并且已经了解了很多索引,我发现这是不可能的以当前类型的索引为例。实际上,我还没有找到任何其他数据库可以做到这一点

事实仍然是,最终列表需要由db手动排序,但排序仍然非常快,因此这可能不是一个大问题。谢谢你的回答


如果我错了,请纠正我;-)

问题不在于子查询。子查询每次都不同,并自动生成。但我们甚至可以举一个例子,其中子查询是一个ID列表。问题是需要对列表进行排序。这还不足以进行充分的猜测,但如果使用左连接,并在BIGTABLE上基于(id、其他可能的子查询列、标题)的索引作为覆盖索引,查看子查询可能会更好。是的,我同意filesort是个坏名字。我只是在思考解释告诉我的东西。我只是觉得有点奇怪,像我的例子那样,如果不进行排序,就无法完全索引一个简单的查询。虽然考虑了不同索引的工作原理,但我也找不到一个好的解决方案:)