我正在使用Oracle来计算人的步行速度。我有一张表:
Name timestamp latitude longitude
Billy 2014-10-10 10:10:12 x1 y1
Billy ... x2 y2
...
Jim k1 m1
Jim k2 m2
...
Kate l1 n1
Kate l2 n2
我想选择任何一分钟内平均速度在5-7米/分钟之间的人。这是我使用Haversin'law计算从A点到B点的距离的代码。
CREATE INDEX PIndex
ON table1 (phoneid,timestamp,gps_latitude,gps_longitude)
SELECT a.phoneid
,a.gps_latitude as alat
,a.gps_longitude as along
,b.gps_latitude as blat
,b.gps_longitude as blong
,3956 * 2 * ASIN(SQRT( POWER(SIN((alat - abs(blat)) * pi()/180 / 2), 2) + COS(along * pi()/180 ) * COS(abs(blong) * pi()/180)
* POWER(SIN((along - blong) * pi()/180 / 2), 2) ))
AS distance
From Table1 a
inner join Table1 b
on a.phoneid = b.phoneid
and a.timestamp = DATEADD(mi,1,b.timestamp)
Where distance between 5 and 7
我有两个问题:
(1)如果我的表非常大并且每秒更新一次(比如10 ^ 9行)。我想创建一个索引来加速查询。如何实现我的选择呢?
(2)解决速度问题。是否有任何方法,比如使用Java将表格切割成块来加速查询?
答案 0 :(得分:2)
你有一项艰巨的任务。可能没有简单的适合所有解决方案。 您可以从基于函数的索引开始
CREATE INDEX timestamp_fb_idx ON table1 (DATEADD(MI,1,时间戳))
看看它是否有任何区别。
答案 1 :(得分:0)
首先,我很好奇你打算如何获得10 ^ 100行。如果地球有10 ^ 10个人,那么每个人你需要大约10 ^ 90行。如果人们的坐标每秒存储一次,那么他们应该活10到80年才能填满数据库。
如果仅考虑此查询,最好的索引方法是使用连接条件字段作为主键使此表索引组织。
通常,此查询的加速应基于迭代而不是加入。但总的来说,任务太荒谬了。 Eighter它是一项学习任务(有数百行),或者你错过了它的许多重要部分。