2014-03-06 47 views
0

有没有一种方法来设置一个索引,不使用任何类型的文件在mysql中进行以下查询?优化子查询和排序

SELECT * FROM bigtable WHERE id IN ([a indexed subquery]) ORDER BY title; 

这种情况下的ID是主键。使用Innodb。 对这种查询做一个EXPLAIN总是会说它使用的是filesort。

编辑1:

,因为它在我的情况是自动生成的子查询并不重要。 但对于参数的缘故让让这样的查询,而不是

SELECT * FROM bigtable WHERE id IN (4,6,8,7,10,40,21,54...) ORDER BY title; 

有什么办法来索引此查询不使用文件排序为“ORDER BY”?

奖金问题:有没有其他数据库可以做到这一点?

+0

实在不够充分估计,但看着你的子查询可能与左加入更好,基于(ID在你的BigTable的索引,其他可能的子查询列,标题)作为覆盖索引。 – DRapp

回答

0

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

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

如果我错了,请大家指正;-)

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; 

它很难帮助更多的不知道表结构或子查询。

编辑:嗯,我有文件排序有类似的问题,并得到了周围通过以下方式(修改第一提议的解决方案):

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)

+0

问题不在于子查询。子查询每次都不同,并自动生成。但是我们甚至可以举例子查询是ID列表的例子。问题是该列表需要排序。 – doep

0

在某些情况下,MySQL将使用索引进行排序。如果您有bigtable(title)索引,那么下面的查询应该使用索引:

select * 
from bigtable 
order by title; 

我希望你的查询也使用索引,除非“索引子查询”使优化器us.ea不同的执行计划。 MySQL做得相当不错documenting其优化策略为order by

1

在这里进行文件操作是否真的很糟糕?从我从例如here它可能被称为FILEsort,但实质上它只是一种普通的排序;你在ORDER BY明确要求。

我假设系统使用该索引的id字段来查找相关记录这是由存储在id阶定义,提取发现的记录的标题值,然后在返回前导致各种它给客户端。

我不能想出一个避免这种情况的好方法,也不会这么做。如果你确实真的想要,你可以尝试以某种方式将PK更改为TITLE + ID字段,然后让查询扫描整个表以正确的顺序找到正确的ID。但是,这将是非常低效的,并且只有(可能)带有单线程工作。一旦它发生在多个线程上,你仍然需要累积结果并对结果进行排序以确保输出。考虑到可能存在的优化可能会'搞砸''开始'到'结束'方法'我不会感到惊讶,即使在最好的情况下,系统也会安全地进行排序。

+0

是的,我同意filesort是一个坏名字。我只是在反思“说明”告诉我什么。 – doep

+0

我只是觉得有点奇怪,没有办法完全索引像我的示例一样的简单查询,而没有进行排序。虽然考虑如何不同的索引工作,我无法找到一个好的解决方案:) – doep