2010-07-23 38 views
0

我正在開發一個跟蹤用戶當前位置並將其存儲到SQLite數據庫的應用程序。一切工作正常,但現在我有問題時查詢數據庫超過1000條記錄的軌道,它需要近1.5分鐘。在我的桌面上,它只需要1秒。爲Android sqlite優化SQL語句

我知道這是一個查詢與許多子選擇,但我不能以另一種方式得到正確的結果。在我看來,這屬於像avg()和sum()這樣的集合函數。

這裏是我的查詢:

Cursor c = readableDB 
    .rawQuery(
      "SELECT DISTINCT t._id , title , strftime('%Y-%m-%d' , starttime , 'unixepoch' , 'localtime') as date , description, " 
      + "round((SELECT sum(distToPrev)/1000 FROM positions p WHERE p.trackid=t._id) , 2) as distance , " 
      + "(SELECT count(latitude) FROM positions p WHERE p.trackid=t._id) as waypoints, " 
      + "(SELECT (avg(speed)*3.6) FROM positions p WHERE p.trackid=t._id) as avgspeed, " 
      + "(SELECT (max(speed)*3.6) FROM positions p WHERE p.trackid=t._id) as maxspeed, " 
      + "(SELECT sum(altitudeUP) FROM positions p WHERE p.trackid=t._id) as climb , " 
      + "(SELECT avg(heartbeat) FROM heartbeats h WHERE h.trackid=t._id) as avgheartbeat , " 
      + "(SELECT max(heartbeat) FROM heartbeats h WHERE h.trackid=t._id) as maxheartbeat , " 
      + "(SELECT avg(cadence) FROM heartbeats h WHERE h.trackid=t._id) as avgcadence " 
      + "FROM tracks t LEFT JOIN heartbeats h ON t._id = h.trackid WHERE t._id = ?", 
      new String[]{String.valueOf(trackId)}); 
    c.moveToFirst(); 

我怎樣才能優化這個查詢?我已經以這種方式嘗試過了,但結果是錯誤的,花費了相同的時間。

SELECT t._id , title , strftime('%Y-%m-%d' , starttime , 'unixepoch' , 'localtime') as date , description, 
sum(distToPrev)/1000 as distance , 
count(latitude) as waypoints, 
(avg(speed)*3.6) as avgspeed, 
(max(speed)*3.6) as maxspeed, 
sum(altitudeUP) as climb , 
avg(heartbeat) as avgheartbeat , 
max(heartbeat) as maxheartbeat , 
avg(cadence) as avgcadence 
FROM tracks t 
LEFT JOIN heartbeats h ON t._id = h.trackid 
INNER JOIN positions p ON t._id = p.trackid 
    WHERE t._id = ? 

由於2個小時我正在尋找解決方案,我不知道我在做什麼錯。也許我必須休息一下。

編輯:

在這裏,我創建語句:

CREATE TABLE heartbeats(_id INTEGER PRIMARY KEY AUTOINCREMENT, trackid INTEGER NOT NULL, heartbeat INTEGER NOT NULL, cadence INTEGER, timestamp TIMESTAMP); 


CREATE TABLE positions(_id INTEGER PRIMARY KEY AUTOINCREMENT, trackid INTEGER NOT NULL, longitude REAL NOT NULL, latitude REAL NOT NULL, altitude REAL, altitudeUP REAL, speed REAL, accuracy REAL, distToPrev REAL, timestamp TIMESTAMP); 


CREATE TABLE tracks(_id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL, description TEXT, starttime DATETIME NOT NULL, endtime DATETIME); 
+0

指定表別名,但無法將它們用於第一個SELECT列之外。我們不知道哪些表的剩餘部分來自於能夠建議任何有價值的東西...... – 2010-07-23 17:56:15

+0

請張貼您的表架構,幷包括您也有的索引。 – Pentium10 2010-07-23 17:57:19

+0

添加了我的創建語句。表格中沒有索引。 – tarantel 2010-07-23 18:23:06

回答

2

這將做的工作:

SELECT tid, date, waypoints, avg(heartbeat) AS avgheartbeat 
FROM (SELECT t._id AS tid, strftime('%Y-%m-%d' , starttime , 'unixepoch' , 'localtime') AS date, count(latitude) AS waypoints 
     FROM tracks t LEFT JOIN positions p ON t._id = p.trackid 
     WHERE t._id = ? 
     GROUP BY t._id , strftime('%Y-%m-%d' , starttime , 'unixepoch' , 'localtime')) 
    LEFT JOIN heartbeats h ON tid = h.trackid 
GROUP BY tid, date, waypoints 

根據需要添加字段。

1

像這樣的東西可能會關閉。我已經包括了參數中多次查詢通知:

SELECT 
    T._id, 
    T.title, 
    STRFTIME('%Y-%m-%d' , T.starttime , 'unixepoch' , 'localtime') as date, 
    T.description, 
    P_SQ.distance, 
    P_SQ.waypoints, 
    P_SQ.avg_speed, 
    P_SQ.max_speed, 
    P_SQ.climb 
FROM 
    Tracks T 
LEFT OUTER JOIN 
(
    SELECT 
     P.trackid, 
     SUM(P.distToPrev) AS distance, 
     COUNT(P.latitude) AS waypoints, 
     AVG(P.speed) * 3.6 AS avg_speed, 
     MAX(P.speed) * 3.6 AS max_speed, 
     SUM(altitudeUp) AS climb 
    FROM 
     Positions P 
    WHERE 
     P.trackid = ? 
    GROUP BY 
     P.trackid 
) P_SQ ON P_SQ.trackid = T._id 
LEFT OUTER JOIN 
(
    SELECT 
     H.trackid, 
     AVG(heartbeat) AS avg_heartbeat, 
     MAX(heartbeat) AS max_heartbeat, 
     AVG(cadence) AS avg_cadence 
    FROM 
     Heartbeats 
    WHERE 
     H.trackid = ? 
    GROUP BY 
     H.trackid 
) H_SQ ON H_SQ.trackid = T._id 
WHERE 
    T._id = ? 
+0

看起來相當不錯,但現在我得到一個android.database.sqlite.SQLiteException:沒有這樣的列:H_SQ.trackid。在我的桌面上,它的作品。 – tarantel 2010-07-23 19:05:44

3

不要過於簡單化,但我認爲你可以通過查詢過程簡單的索引,你是掃描領域剃了大量的時間把你的查詢。

通過索引字段,您可以減少所有表掃描,隨着記錄數量的增長,查詢速度會變慢。

索引的缺點是空間需求,但根據我在Android上的經驗,它很少是一個因素。

+0

好的,謝謝。我會嘗試。 – tarantel 2010-07-23 19:08:20