2011-12-02 35 views
3

只是想确保我理解这个权利。如果我有巨大的数据集和数据库的结构是这样的,我所要做的mysql子查询是否总是使用临时表?无法索引

SELECT ... FROM(SELECT ...)AS TMP

这是否意味着查询将总是很慢,没有办法通过添加索引等来解决这个问题?

回答

1

绝对不是......它基于索引和优化技术。根据数据最可能被查询的最小粒度构建查询并帮助索引。示例...如果您有订单表,则可以根据订单日期或客户进行查询。但是,如果您想要在某个日期范围内查询客户的订单,则可以使用更好的索引(customerID,orderDate)而不是(orderDate,Customer)。

第一个索引会在您要查找的最接近日期范围内跳转到有问题的客户,然后转到该日期范围的末尾并完成。

第二个索引将不得不经过您范围内的每个日期(这会让很多客户跳过),然后获取一个客户的记录,然后转到下一个日期并重新执行。

+0

似乎没有解决这个问题呢?在SQL Server中,当从派生表或视图执行“SELECT”时,优化器会扩展派生表定义,并可以将谓词向下推并使用索引。据我了解,OP会询问它是否会始终将其物化为MySQL中的非索引临时表。 –

+1

@MartinSmith,它实际上是..每个“...这是否意味着查询将总是很慢...” – DRapp

+1

我可能更感兴趣的标题问题“是否MySQL子查询总是使用临时表?不被索引“。假设在col1,col2上有一个包含复合索引的表'foo',MySQL将如何评估SELECT * FROM(SELECT col1,col2 FROM foo WHERE col1 = 2)AS tmp WHERE col2 = 3'? –

0

你需要阅读关于索引的一些文献,因为它有助于理解你的结构是如何工作的,你的索引是如何存储的以及它的位置和它的引用值有什么关系。在MySQL中,它们基本上是3种结构类型B-Tree,Hash,R-TRee。每个不同的引擎(MyISAM,InnoDB,NDB)都有自己的索引性能细微差别,例如NDB引擎具有B树索引,但事实上它像T树一样工作。数据类型也非常可观。如果您使用不同类型的索引将无法工作,否则会降低某些查询性能。所以谈论加入他们的表现是基于早期阶段所做出的决定,这正是我之前所说的。