训练时间表查询 - SQLite太慢了,CoreData反而?

时间:2010-08-30 11:27:16

标签: iphone objective-c sqlite core-data

编辑:我发现了问题,这与下面的内容完全无关。这是由于我做了一个按位比较,我没有在下面提到 - 我认为这是不相关的 - 我删除了这个(并找到了另一种解决方案),我的查询现在在<设备上1秒钟。

我正在开发我的第一个iPhone应用程序,它正在顺利进行。它是查找某个列车网络的列车时刻表的应用程序。我有一个包含大约11,000行的SQLite数据库,这些行包含我用来计划旅程的数据。

表的结构如下:

from     depart      to         arrive     trainid
--------------------------------------------------
STNA     06:20       STNB       06:24      TRAINA
STNB     06:25       STNC       06:29      TRAINA
STNC     06:30       STND       06:35      TRAINA
STNA     07:23       STNC       07:30      TRAINB
STNC     07:32       STNE       07:40      TRAINB
STNE     07:41       STNF       07:50      TRAINB

FROMTO字段是路径上3个字母的IDS,DEPARTARRIVE字段是时间戳,TRAINID字段是特定列车行程中所有车站共有的标识符(即从STNA到STND的06:20列车上的所有站点共用相同的列车)。

当我想知道哪些列车将把我从STNA带到STND时,我会做以下查询:

SELECT t1.from, t1.depart, t2.to, t2.arrive, t1.trainid FROM trains t1, trains t2 WHERE t1.trainid = t2.trainid AND t1.depart < t2.arrive AND t1.from = 'STNA' AND t2.to = 'SNTD';

这在火车桌上进行了自我加入(t1.depart&lt; t2.arrive部分是为了从STNA-> STND而不是STND-> STNA找到列车。)

这很好用,但它在iphone上非常慢(好吧你可能会说不太好),运行大约需要10秒(返回大约80个结果)。我意识到这很可能是因为11,000行表正在加入自身 - 但我对如何优化它感到茫然。顺便说一下,我正在使用FMDB。

我想我需要沿着CoreData路线走下去,但作为iPhone平台的新手,我希望避免这个项目。您认为CoreData会在这种情况下提供显着的性能优势吗?作为纯粹SQL背景的人,我会很感激有关如何最好地继续使用CoreData的任何指示 - 我可以使用CoreData进行自我连接,还是应该以不同方式对数据进行建模?

编辑: 这是关于查询即时执行的解释的输出:

add  opcode        p1     p2     p3     p4                                        p5     comme
---  ------------  -----  -----  -----  ----------------------------------------  -----  -----
0    Trace         0      0      0                                                00          
1    String8       0      1      0      GRY                                       00          
2    String8       0      2      0      FST                                       00          
3    Goto          0      47     0                                                00          
4    OpenRead      0      2      0      7                                         00          
5    OpenRead      2      377    0      keyinfo(1,BINARY)                         00          
6    OpenRead      1      2      0      7                                         00          
7    OpenRead      3      1107   0      keyinfo(1,BINARY)                         00          
8    IsNull        1      42     0                                                00          
9    Affinity      1      1      0      ab                                        00          
10   SeekGe        2      42     1      1                                         00          
11   IdxGE         2      42     1      1                                         01          
12   IdxRowid      2      3      0                                                00          
13   Seek          0      3      0                                                00          
14   Column        0      6      4      0                                         00          
15   IsNull        4      41     0                                                00          
16   Affinity      4      1      0      db                                        00          
17   SeekGe        3      41     4      1                                         00          
18   IdxGE         3      41     4      1                                         01          
19   IdxRowid      3      3      0                                                00          
20   Seek          1      3      0                                                00          
21   Column        0      5      3                                                00          
22   Column        1      5      5                                                00          
23   Ne            5      40     3      collseq(BINARY)                           6a          
24   Column        0      3      5      0                                         00          
25   RealAffinity  5      0      0                                                00          
26   Column        1      3      3      0                                         00          
27   RealAffinity  3      0      0                                                00          
28   Ge            3      40     5      collseq(BINARY)                           6b          
29   Column        1      2      3                                                00          
30   Ne            2      40     3      collseq(BINARY)                           69          
31   Column        2      0      6                                                00          
32   Column        0      3      7      0                                         00          
33   RealAffinity  7      0      0                                                00          
34   Column        1      2      8                                                00          
35   Column        1      4      9      0                                         00          
36   RealAffinity  9      0      0                                                00          
37   Column        0      5      10                                               00          
38   Column        0      6      11     0                                         00          
39   ResultRow     6      6      0                                                00          
40   Next          3      18     0                                                00          
41   Next          2      11     0                                                00          
42   Close         0      0      0                                                00          
43   Close         2      0      0                                                00          
44   Close         1      0      0                                                00          
45   Close         3      0      0                                                00          
46   Halt          0      0      0                                                00          
47   Transaction   0      0      0                                                00          
48   VerifyCookie  0      8      0                                                00          
49   TableLock     0      2      0      stops                                     00          
50   Goto          0      4      0                                                00          

2 个答案:

答案 0 :(得分:1)

虽然它可以使用几个不同的后备存储,但SQLite是CoreData可以使用的之一。

出于这个原因,您不应期望CoreData有更好的性能。 CoreData没有什么神奇之处。

我怀疑问题出在您的查询中。您的查询解释计划的输出是什么?我认为你会发现它正在进行全表扫描,并且在正确的列上创建的索引可以将查询时间减少到几乎没有。

答案 1 :(得分:0)

这是一个更切向的答案 - 如果站A和站D之间没有直达列车,意味着您唯一的方式是连接 - 通过TrainA从站A到站X,然后通过TrainM从站X到站D,您的SQL是会变得相当笨拙不是吗。我不得不使用图表(数学公式)在合理的时间内完成这项工作。最后我在www.bharatbyrail.com上发了言。看到它给你一些想法。