2009-07-05 6 views
2

Ich habe einige SQL-Abfragen, die meine iPhone App verlangsamen.Wie sqlite Abfrage mit Daten & substr optimieren?

Ich habe 2 Muster, die ich in meiner App wiederholen. Die erste ist mit substr: (. Dieser Lauf für die mayority des Alphabets ist für eine Kontaktliste)

SELECT Id FROM [Table] WHERE UPPER(substr(Name,1,1))='A' ORDER BY Name" 

Der andere komplex mit Datum ist:

SELECT Id,customerCode, 
case 
when DueDate>=datetime('now','-100 years') AND DueDate<=datetime('now','-1 days') then 'Past due' 
when DueDate<datetime('now') then 'Today' 
when DueDate>=datetime('now') AND DueDate<=datetime('now','15 days') then '15' 
when DueDate>=datetime('now','16 days') AND DueDate<=datetime('now','30 days') then '30' 
when DueDate>=datetime('now','31 days') AND DueDate<=datetime('now','45 days') then '45' 
when DueDate>=datetime('now','46 days') AND DueDate<=datetime('now','60 days') then '60' 
when DueDate>=datetime('now','61 days') AND DueDate<=datetime('now','90 days') then '90' 
when DueDate>=datetime('now','91 days') then '> 90' 
end As Key, 
COUNT(*) As Total, TimeStamp 
FROM debt 
GROUP BY customerCode, 
case 
when DueDate>=datetime('now','-100 years') AND DueDate<=datetime('now','-1 days') then '-1' 
when DueDate<datetime('now') then 'Today' 
when DueDate>=datetime('now') AND DueDate<=datetime('now','15 days') then '15' 
when DueDate>=datetime('now','16 days') AND DueDate<=datetime('now','30 days') then '30' 
when DueDate>=datetime('now','31 days') AND DueDate<=datetime('now','45 days') then '45' 
when DueDate>=datetime('now','46 days') AND DueDate<=datetime('now','60 days') then '60' 
when DueDate>=datetime('now','61 days') AND DueDate<=datetime('now','90 days') then '90' 
when DueDate>=datetime('now','91 days') then '> 90' 
end 

In In beiden Fällen habe ich Index für das Datum & das Varchar-Feld.

Der 1. Lauf ok im Simulator und 11 Sekunden in dem iPod touch nimmt 2 GEN

Die zweite Abfrage ist im iPhone-Simulator (3 sec) & 1 min in dem Gerät zu langsam. Die Daten verwenden das ISO-Datumsformular.

Ich habe tothth eine Cache-Tabelle erstellen (und trigers für die Updates. Die Daten sind live und der Benutzer kann es ändern) für die Daten, aber frage mich, ob es einen besseren Weg gibt.

Antwort

3

Ich habe keine Ahnung, wie die Leistung vergleicht, sondern eine andere Art und Weise die erste Abfrage zu schreiben, gibt es

SELECT Id FROM [Table] WHERE Name LIKE "a%" 

, weil ein beliebige Zeichenfolge% übereinstimmt mit einem oder A beginnt, durch eine beliebige Anzahl von Zeichen.

Weitere Informationen finden Sie unter http://www.sqlite.org/lang_expr.html#like.

Zweitens nehme ich an, dass Sie bei wiederholten Aufrufen von datetime einen Leistungseinbruch erleiden. Können Sie es zu einer einzigen mathematischen Operation komprimieren und dann den Unterschied in Tagen mit einfachen mathematischen Operatoren vergleichen? Zum Beispiel kann die Anzahl der Tage seit dem letzten Weihnachten:

sqlite> select julianday('now') - julianday('2008-12-05'); 
212.743649386801 

SQLite speichert Daten als Strings intern, so dass jedes Mal, wenn Sie datetime nennen es muss vollständig die Datumszeichenfolge analysieren, usw.

+1

Mit der LIKE die Abfrage verbringen 2 Sekunden weniger. – mamcx

0

Sie dies nicht tun wiederholen müssen, dass CASE Operator zweimal - nur GROUP BY CustomerCode, Key wird ausreichen. Wie @Mark vorschlägt, kann die CASE vielleicht durch die Verwendung von Unterschieden in julianday und der Namensauswahl optimiert werden, indem man die Tatsache ausnutzt, dass LIKE standardmäßig Groß- und Kleinschreibung ignoriert (solange Sie nur ASCII-Buchstaben benötigen - leider, Es ist ein dokumentierter Fehler in sqlite, dass die Groß-/Kleinschreibung nicht außerhalb von ASCII funktioniert.