2009-11-23 110 views
0

我有一个查询从〜10,000的表中提取5条记录。 order子句不包含在索引中,但where子句是。如何减少由MySQL扫描的行数

该查询扫描大约7,700行来获取这5个结果,这似乎有点多。不过,我明白,排序标准的复杂性使事情变得复杂。如果有的话,我可以减少扫描的行数吗?

查询看起来是这样的:

SELECT * 
FROM `mediatypes_article` 
WHERE `mediatypes_article`.`is_published` = 1 
ORDER BY `mediatypes_article`.`published_date` DESC, `mediatypes_article`.`ordering` ASC, `mediatypes_article`.`id` DESC LIMIT 5; 

medaitypes_article.is_published索引。

+0

你可以发布表声明的相关位? – shylent 2009-11-23 06:55:09

+2

在发布的查询前面放置'EXPLAIN',运行它并发布输出。 – Asaph 2009-11-23 06:55:18

+0

文章 http://dev.mysql.com/doc/refman/5.0/en/order-by-optimization.html – 2009-11-23 06:56:36

回答

3

“is_published = 1”适用于多少行? 我假设这是... 7.700行?

无论采取哪种方式,完整结果将匹配的WHERE子句必须提取和完全排序的所有排序标准。然后,所有已排序的已发布文章的完整列表将在前5个结果后截断。

也许它可以帮助您查看有关ORDER BY优化的MySQL documentation article,但首先您应该尝试将索引应用于ORDER BY语句中指定的列。这很可能会大大加速事情。

0

当您订购时,您必须遍历所有btree以找出正确的顺序。

10,000条订单记录并不是那么大的担心。请记住,通过适当的索引,RDBMS不会获取整个记录来找出订单。它在保存在磁盘上的btree页面中有索引列,并且页面读取很少,整个btree被加载到内存中并且可以遍历。

0

在MySQL中,您可以创建一个包含多列的索引。我认为你可能需要做的是制作一个包含is_published和published_date的索引。您应该查看EXPLAIN语句的输出,以确保它以智能的方式执行操作,如果不是,则添加索引。