谓词“IN”在设备上非常慢(83倍差异)

时间:2011-06-19 07:10:30

标签: ios core-data

我有一个谓词

predicate = [NSPredicate predicateWithFormat:@“character.id IN%@”,indexs];

它会生成以下SQL:

  

CoreData:sql:SELECT t0.Z_ENT,t0.Z_PK,t0.Z_OPT,t0.ZCHARACTERID,t0.ZMEANING,t0.ZREADING,t0.ZRADICAL,t0.ZSTROKECOUNT,t0.ZCHARACTER,t0.ZFREQUENCY,t0。 ZGRADE,t0.ZJLPTLEVEL,t0.ZKUNREADING,t0.ZHWUNMEANING,t0.ZROMAN,t0.ZHWUN,t0.ZHWUNMORE,t0.ZPHONETICID from ZCHARACTERINFO t0 LEFT OUTER JOCH ZCHARACTER t1 on t0.ZCHARACTER = t1.Z_PK WHERE(t1.ZID IN(?,?,?,?,?,?,?)和t0.Z_ENT =?)ORDER BY t0.ZSTROKECOUNT,t1.ZUNICODE

在模拟器中我得到以下结果:

  

CoreData:注释:sql连接获取时间:0.0478s   CoreData:注释:总获取执行时间:7行为0.0483秒。

设备上的VS(iPhone 3G)

  

CoreData:annotation:sql连接获取时间:3.9627s   CoreData:注释:总获取执行时间:7行为3.9789秒。

SQLite解释查询计划显示我正在使用索引(ZID在模型中定义了索引):

selectid    order       from        detail                                                                                      
----------  ----------  ----------  ---------------------------------------------------------------------------------------------
0           0           0           SEARCH TABLE ZCHARACTERINFO AS t0 USING INDEX ZCHARACTERINFO_Z_ENT_INDEX (Z_ENT=?) (~10 rows)
0           1           1           SEARCH TABLE ZCHARACTER AS t1 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)                 
0           0           0           EXECUTE LIST SUBQUERY 1                                                                     
0           0           0           USE TEMP B-TREE FOR ORDER BY                                                                
CPU Time: user 0.000395 sys 0.000184

在数据库中,我在字符表中有20,900行,在characterinfo表中有62,000行。

我想知道为什么它在设备上这么慢。我错过了什么吗?有没有办法改善?感谢。

更新 我怀疑加入是问题所在。所以我试着将t1.ZID移动到t0表中,以便我可以摆脱连接表。新查询成为:

  

SELECT t0.Z_ENT,t0.Z_PK FROM ZCHARACTERINFO t0 WHERE(t0.ZCHARACTERID IN(?,?,?,?,?,?,?)和t0.Z_ENT =?)ORDER BY t0.ZSTROKECOUNT

新查询大约使用了1.8秒。它有所改善,但似乎仍然很慢。它是否会像那么慢?

2 个答案:

答案 0 :(得分:1)

第一次查询的缓慢很可能源于LEFT OUTER JOIN。

根据您报告的数据库大小,我会说1.8秒非常快,特别是在iPhone 3G上。

如果仍然不够快,我建议使用较低级别的数据库框架,它允许您直接操作数据库的模式并使用其他工具来加速查询。

答案 1 :(得分:0)

谢谢你的帮助。解决了这个问题。

  1. 加入很慢。消除了连接,时间缩短到1.8~2s。 (见上面的更新)
  2. 查询未在Z_ENT上使用索引或仅使用索引。对于ZCHARACTERID,它仍然执行全表扫描。所以我在ZCHARACTERINFO(ZCHARACTERID,Z_ENT)上添加了“CREATE INDEX CID_Z_ENT_INDEX。”查询时间缩短为0.05秒。
  3. 注意:在添加新索引之后,解释查询计划仍然显示它使用Z_ENT索引。必须删除Z_ENT索引才能使用CID_Z_ENT_INDEX。不知道为什么。