我想在MySQL数据库中从表中获取两行。这两排一定是我点的第一排和最后一排。为了达到这个目的,我做了两个问题,这两个:
SELECT dateBegin, dateTimeBegin FROM worktime ORDER BY dateTimeBegin ASC LIMIT 1;";
SELECT dateBegin, dateTimeBegin FROM worktime ORDER BY dateTimeBegin DESC LIMIT 1;";
我决定不获取整个集合,而选择PHP中的第一个和最后一个,以避免可能非常大的数组。我的问题是,我有两个问题,我不知道这有多有效。例如,我想将它们与UNION结合起来,但是我仍然需要对未排序的列表进行两次排序,这也是我要避免的,因为第二次排序与第一次排序完全相同
我想先订购一次,然后选择此订购列表的第一个和最后一个值,但我不知道比使用两个查询的方法更有效的方法。我知道性能的好处不会很大,但是我知道列表正在增长,而且随着它们越来越大,我为一些表执行这一部分,我需要最有效的方法来做到这一点。
我发现了一些类似的话题,但没有一个涉及到这个特殊的表演问题。
任何帮助都是非常感谢的。
最佳答案
(这既是一个“答案”,也是对某些评论中的错误的反驳。)
INDEX(dateTimeBegin)
将方便
SELECT ... ORDER BY dateTimeBegin ASC LIMIT 1
和另一端的相应行,使用DESC
。MAX(dateTimeBegin)
将只找到该列的最大值;它不会直接找到该行中的其余列。这需要一个子查询或JOIN
。INDEX(... DESC)
--MySQL忽略了DESC
。这几乎从来都不是缺点,因为优化器愿意在索引中任意一个方向。重要的是ORDER BY x ASC, y DESC
不能使用INDEX(x, y)
,也不能使用INDEX(x ASC, y DESC)
。这是MySQL的缺陷。(除此之外,我同意戈登的“回答”。)( SELECT ... ASC )
UNION ALL
( SELECT ... DESC )
与两个单独的选择相比,不会提供太多(如果有的话)性能优势。选择使代码更简单的技术。
拥有一个
DATETIME
(或TIMESTAMP
)字段几乎总是比拆分DATE
和/或TIME
更好。SELECT DATE(dateTimeBegin), dateTimeBegin ...
工作简单,而且“足够快”。另请参见函数DATE_FORMAT()
。我建议删除dateBegin
列并相应地调整代码。请注意,缩小表实际上可能会比DATE()
的成本更快地加快处理速度。(差异将是无穷小。)如果没有以
dateTimeBegin
开头的索引,任何一种技术都会很慢,并且随着表大小的增长而变慢。(我确信它可以在一次完整的传递中同时找到MIN()
和MAX()
,并且不需要排序就可以完成。这对ORDER BYs
需要两次完整的传递,加上两次排序;5.6可能有一个几乎消除排序的优化。)如果有两行具有完全相同的min
dateTimeBegin
,那么您将无法预测得到哪一行。