MySQL选择有效的第一行和最后一行

时间:2016-01-04 20:34:35

标签: php mysql sql performance processing-efficiency

我想在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结合起来,但是我仍然需要两次排序未排序的列表,这也是我想要避免的,因为第二次排序与第一次排序完全相同

我想订购一次,然后选择这个有序列表的第一个和最后一个值,但我不知道一个有两个查询的方法更有效。我知道性能优势不会很大,但我知道这些列表正在增长,随着它们变得越来越大,我为某些表执行此部分,我需要最有效的方法来实现这一点。 我发现了几个类似的主题,但没有一个问题解决了这个特定的性能问题。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

您的查询没问题。你想要的是worktime(dateTimeBegin)的索引。 MySQL应该足够聪明,可以将此索引用于ASCDESC种类。如果你测试它,但它不是,那么你需要两个索引:worktime(dateTimeBegin asc)worktime(dateTimeBegin desc)

您是否运行一个或两个查询取决于您。一个查询(由UNION ALL连接)稍微提高效率,因为您只有一次数据库往返。但是,两个可能更容易适合您的代码,并且性能的差异对于大多数目的而言并不重要。

答案 1 :(得分:1)

(这既是一个“答案”,也是对一些评论中错误的反驳。)

SELECT ... ORDER BY dateTimeBegin ASC LIMIT 1

将使用DESC促进MAX(dateTimeBegin)和另一端的相应行。

JOIN只会找到 该列的最大值;它将直接找到该行中的其余列。这需要子查询或INDEX(... DESC)

DESC - MySQL ORDER BY x ASC, y DESC忽略。这几乎从来都不是一个缺点,因为优化器愿意通过索引进行任一方向。重要的是INDEX(x, y) 无法使用INDEX(x ASC, y DESC)( SELECT ... ASC ) UNION ALL ( SELECT ... DESC ) 。这是MySQL的缺陷。 (除此之外,我同意戈登的'回答'。)

DATETIME

与两个单独的选择相比,不会提供太多(如果有的话)性能优势。选择使您的代码更简单的技术。

与分割出TIMESTAMP和/或DATE相比,拥有单个TIME(或SELECT DATE(dateTimeBegin), dateTimeBegin ...)字段几乎总是更好。 DATE_FORMAT()工作简单,“足够快”。另请参见函数dateBegin。我建议删除DATE()列并相应地调整代码。请注意,缩小表格实际上可能会使处理速度超过dateTimeBegin的成本。 (差异将是无穷小的。)

如果没有索引使用MIN()启动,任何技术都会很慢,并且随着表的大小增加而变慢。 (我很确定它只能在一次完整传递中找到两者 MAX()ORDER BYs,并且无需排序即可完成。dateTimeBegin对将会{需要两个完整的传递,加上两个类; 5.6可能有一个几乎消除排序的优化。)

如果有两行具有完全相同的分钟{{1}},那么您得到的哪一行将无法预测。