我有一个这样的查询:
SELECT article FROM table1 ORDER BY publish_date LIMIT 20
ORDER BY是如何工作的?它将排序所有记录,然后获得前20条,还是将获得20条记录并根据publish_date字段对它们进行排序?
如果是最后一篇,你不能保证真的得到最近的20篇文章。
我有一个这样的查询:
SELECT article FROM table1 ORDER BY publish_date LIMIT 20
ORDER BY是如何工作的?它将排序所有记录,然后获得前20条,还是将获得20条记录并根据publish_date字段对它们进行排序?
如果是最后一篇,你不能保证真的得到最近的20篇文章。
当前回答
如果有一个合适的索引,在这个例子中是publish_date字段,那么MySQL不需要扫描整个索引来获得请求的20条记录——这20条记录将在索引的开始处找到。但如果没有合适的索引,则需要对表进行完整扫描。
2009年有一篇关于MySQL性能的博客文章。
其他回答
正如@James所说,它将排序所有记录,然后获取前20行。
因此,您可以保证获得20篇首次发表的文章,更新的文章将不会显示。
在你的情况下,我建议你添加desc到order的publish_date,如果你想要最新的文章,那么最新的文章将是第一个。
如果你需要保持结果的升序,并且仍然只想要10篇最新的文章,你可以让mysql对你的结果排序两次。
下面的查询将对结果进行降序排序,并将结果限制为10(即括号内的查询)。它仍然会按降序排序,我们不满意,所以我们要求mysql再排序一次。现在我们有了最后一行的最新结果。
select t.article
from
(select article, publish_date
from table1
order by publish_date desc limit 10) t
order by t.publish_date asc;
如果你需要所有的列,这样做:
select t.*
from
(select *
from table1
order by publish_date desc limit 10) t
order by t.publish_date asc;
当我手动编写查询以检查数据库中的各种内容时,我使用了这种技术。我还没有在生产环境中使用过它,但是现在当我对它进行基准测试时,额外的排序不会影响性能。
如果有一个合适的索引,在这个例子中是publish_date字段,那么MySQL不需要扫描整个索引来获得请求的20条记录——这20条记录将在索引的开始处找到。但如果没有合适的索引,则需要对表进行完整扫描。
2009年有一篇关于MySQL性能的博客文章。
LIMIT通常应用于最后一个操作,因此结果将首先排序,然后限制为20。事实上,只要找到前20个排序结果,排序就会停止。
LIMIT子句可用于限制SELECT语句返回的行数。LIMIT接受一个或两个数值参数,它们必须都是非负整数常量(除非使用预处理语句)。
有两个参数,第一个参数指定要返回的第一行的偏移量,第二个参数指定要返回的最大行数。初始行偏移量为0(不是1):
SELECT * FROM tbl LIMIT 5,10;#检索第6-15行
要检索从某个偏移量到结果集末尾的所有行,可以使用一些较大的数字作为第二个参数。该语句检索从第96行到最后一行的所有行:
SELECT * FROM tbl LIMIT 95,18446744073709551615;
通过一个参数,该值指定从结果集开始返回的行数:
SELECT * FROM tbl LIMIT 5;#检索前5行
换句话说,LIMIT row_count等价于LIMIT 0, row_count。
所有详细信息:http://dev.mysql.com/doc/refman/5.0/en/select.html
它会先点餐,然后再拿到前20份。数据库还将处理ORDER BY之前的WHERE子句中的任何内容。