用SQL有效地搜索下一个(更大)的密钥

时间:2013-09-08 11:48:53

标签: mysql sql database

我有一个带有元组的表,其中时间戳(时间)不是连续的,但(为简单起见,我们可以假设)是唯一的。

time | value
------------
0    |4
3    |2
5    |6
8    |10
9    |5
13   |-1
15   |-3
...  |...

我面临的问题是找到“给定时间T的下一个元组”(< - next(T);),例如, next(4) - > < 5,6>,或next(5) - > < 8,10取代。此外,由于这个数据保存在MySQL数据库中,我宁愿用SQL实现这一点。但是,时间限制需要在O(log n)中找到相应的元组。

乍一看,我尝试了以下SQL语句(我希望我的伪代码是可以理解的):

<time, value> = next(T) {

    return (select * from table
        where time = (select min(time) from table
            where time > T))
}

但是,这并不能在合理的时间内给出结果。我猜“从表中选择min(时间),其中时间&gt; find”需要O(n)时间。当然,我知道在有序列表中执行搜索只需要O(log n)时间,但我不知道如何在SQL中执行此操作。这甚至可能吗?如果是这样,它是如何工作的?

谢谢!


供您参考:

(1)目前,我的解决方案将相应的数据缓存在内存中并最初对其进行排序。这样我就可以在O(log n)时间内找到下一个元组。但是,这会消耗大量内存,我宁愿在DBMS中进行“内联”,这在高速缓存等方面肯定是高度优化的。

(2)我可以想象一个解决方案,其中数据按时间顺序保存在数据库中,但我不知道如何确保在SQL中排序或实现相应的搜索算法。 : - /

(3)我知道索引等,如果我将时间声明为主键,但我不知道如何在O(log n)中找到下一个,那么它会提高性能。

1 个答案:

答案 0 :(得分:3)

  1. 您需要确保时间列存在索引。您可以通过检查此命令的结果来检查索引是否存在:

    show index from table;

    如果时间列是表的主键,那么索引几乎肯定存在。索引对于时间列中的有效搜索是必需的。你会得到带有正确索引的O(log n)性能,如果不是常量时间查找(只是阅读更多关于btree的信息)。

    MySQL使用B树索引,它允许以对数时间进行查找和顺序遍历。这意味着,如果MySQL正确使用索引,则在对数时间内找到给定时间的下一个更高时间。情况并非总是这样,你必须尝试这一点。如果它不起作用,你必须提供MySQL执行提示,以使其正确使用索引。

  2. 按时间排序结果,然后使用limit关键字仅获取结果集中的第一个结果:

    select * from table
        where time > T
        order by time
        limit 1