优化子查询和排序

时间:2014-03-06 01:00:47

标签: 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,6,8,7,10,40,21,54...) ORDER BY title; 

有没有办法索引这个不使用“ORDER BY”文件的查询?

奖金问题:还有其他数据库可以做到吗?

4 个答案:

答案 0 :(得分:1)

在这里进行文件存储操作真的很糟糕吗?从我得到的,例如here它可能被称为FILEsort,但实质上它只是一种普通的类型;您在ORDER BY明确要求的内容。

我假设系统正在使用id字段上的索引来查找id中存储的定义的相关记录 - 订单,提取标题找到的记录中的值,然后在将结果返回给客户端之前对结果进行排序。

我无法想出一个避免这种情况的好方法,也不会为什么会这样。如果你真的,真的,真的想,你可以尝试以某种方式将PK更改为TITLE + ID字段,然后让查询扫描整个表以找到正确的ID是正确的顺序。但这将是非常低效的,并且只能(可能)使用单线程工作。一旦它突破多个线程,你仍然必须累积结果并对结果进行排序以确保输出。考虑到可能存在优化“搞砸”天真的“从开始到结束的扫描方式”的可能性,即使在最好的情况下,系统也会安全地进行排序并且无论如何都不会太惊讶

答案 1 :(得分:0)

您是否有权在数据库(或同一个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;

如果不是,那就试试这个:

SELECT b.* 
FROM bigtable 
JOIN (SELECT id FROM bigtable WHERE "where conditions") t ON t.id = b.id;

在不知道表结构或子查询的情况下,更难以帮助更多。

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

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;

这里我在临时表的“标题”字段中添加索引,并按此排序。在我的情况下,这样做意味着MySQL不必使用filesort来给我一个有序的结果。我希望这有帮助。 (顺便说一句,bigtable有多少行,以及索引子查询中通常有多少个id)

答案 2 :(得分:0)

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

select *
from bigtable
order by title;

我希望您的查询也使用索引,除非“索引子查询”导致优化器使用不同的执行计划。 MySQL为order by

的优化策略documenting做得非常好

答案 3 :(得分:0)

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

事实仍然是最终列表需要由db手动排序,但排序仍然非常快,所以这可能不是一个大问题。感谢所有的答案!

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