Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Advanced Core Data
Search
Sing Jie Lee
November 20, 2015
Technology
47
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Advanced Core Data
Sing Jie Lee
November 20, 2015
More Decks by Sing Jie Lee
See All by Sing Jie Lee
Infocomm Media Youth Festival 2016 - Career Talk
singjie
0
62
Sprite Kit
singjie
0
65
SiriKit
singjie
0
210
React Native
singjie
1
94
Arduino
singjie
0
48
Software Engineering
singjie
0
63
Amazon Echo and Home Integration
singjie
0
110
CS3216 Garena Project X
singjie
0
59
Life
singjie
0
46
Other Decks in Technology
See All in Technology
GoにおけるFFIのこれまでとこれから
goccy
4
1.2k
GoCon2026 - Open Source, Open World
sanposhiho
2
560
2026-09-10 【Snowflake World Tour Tokyo 2026】dbt Core と Snowflake で実現する多層的なデータガバナンス / Multi-Layered Data Governance Powered by dbt Core and Snowflake
civitaspo
0
240
PfEingのアプローチで働こう
rindrics
0
200
作り直せるコードは迅速に 作り直せないDBは慎重に - AI時代のプロダクトエンジニアが「判断の不可逆性」で開発速度を変える話
kinosuke01
0
280
例外の正しい扱い方 そのエラー try-catchして大丈夫?
jinwatanabe
3
370
KPIだけでは評価できないプロダクトが考えるべき Evalsという第二の評価系 / Beyond KPIs: Evals as a Second Evaluation Framework for Products #PdEConf
aki_iinuma
4
3.8k
TinyGo 開発サイクルを高速化する:Go で作るエミュレータ入門
zozotech
PRO
1
130
#jawssonic2026 あの時代が悪かった ~動かなかったSageMakerと共に迎えたイベント当日~
ktkn1129
0
140
【視聴者参加型!】AWSセキュリティアンチパターンクイズ
syoshie
0
460
Reactの設計論
uhyo
10
2.9k
生成AIのテナント制御とシャドーMCP対策 | AIを"止めずに"、情報を守る
yukun
0
130
Featured
See All Featured
Building Adaptive Systems
keathley
44
3.2k
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
820
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
230
New Earth Scene 8
popppiees
3
2.5k
Un-Boring Meetings
codingconduct
0
410
Deep Space Network (abreviated)
tonyrice
0
290
Why You Should Never Use an ORM
jnunemaker
PRO
61
10k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
680
HTML-Aware ERB: The Path to Reactive Rendering @ RubyCon 2026, Rimini, Italy
marcoroth
4
600
Designing Powerful Visuals for Engaging Learning
tmiket
1
530
Transcript
CORE DATA LEE SING JIE
ARDUINO…
UNDERSTANDING CORE DATA IN DEPTH
UNDERSTANDING CORE DATA IN DEPTH
GUI BROWSER
COMMAND LINE BROWSER $ sqlite3 /Users/singjie/present/ main-25142226 SQLite version 3.8.5
2014-08-15 22:37:57 Enter ".help" for usage hints. sqlite>
Z_METADATA
Z_METADATA - PLIST
Z_PRIMARYKEY
Z_ENT
SUBCLASSING SHOULD YOU?
SUBCLASSING
SUBCLASSING
SUBCLASSING - Z_PRIMARYKEY
SUBCLASSING - Z_ENT
SUBCLASSING - Z_ENT
SUBCLASSING - WHAT IS INDEXING?
CHECKING ON QUERY’S EFFICIENCY
sqlite> explain query plan select * from ZBTMessage where ZMSGID
= 2; 0|0|0|SEARCH TABLE ZBTMessage USING INDEX ZBTMESSAGE_ZMSGID_INDEX (ZMSGID=?) USING EXPLAIN QUERY PLAN
sqlite> explain query plan select * from ZBTMessage where ZMSGID
= 2; 0|0|0|SEARCH TABLE ZBTMessage USING INDEX ZBTMESSAGE_ZMSGID_INDEX (ZMSGID=?) USING EXPLAIN QUERY PLAN
sqlite> explain query plan select * from ZBTInvite where ZINVITEID
= 2; 0|0|0|SCAN TABLE ZBTInvite USING EXPLAIN QUERY PLAN
SUBCLASSING - Z_ENT ZBTBuzzClub - 50k rows (Z_ENT == 16)
ZBTBuzzUser - 50k rows (Z_ENT == 15) ZBTBuzz - ~100k rows Indexes: ‣ Z_ENT ‣ Z_BUZZ_ID sqlite will always use Z_ENT index SELECT * from ZBTBuzz where Z_ENT = 16 AND Z_BUZZ_ID = 123;
SUBCLASSING - Z_ENT Indexes: ‣ Z_ENT ‣ Z_BUZZ_ID sqlite> explain
query plan select * from ZBTBuzz where Z_ENT = 16 AND Z_BUZZ_ID = 123; 0|0|0|SEARCH TABLE ZBTBuzz USING INDEX ZBTBuzz_Z_ENT_INDEX (Z_ENT=?) SELECT * from ZBTBuzz where Z_ENT = 16 AND Z_BUZZ_ID = 123;
SUBCLASSING - Z_ENT INDEX ZBTBuzzClub - 50k rows (Z_ENT ==
16) ZBTBuzzUser - 50k rows (Z_ENT == 15) ZBTBuzz - ~100k rows ZBTBuzzClub - 50k rows (Z_ENT == 16) ZBTBuzzClub - 1 row (Z_BUZZ_ID = 123) 1 2 3 SELECT * from ZBTBuzz where Z_ENT = 16 AND Z_BUZZ_ID = 123;
SUBCLASSING - Z_BUZZ_ID INDEX ZBTBuzzClub - 50k rows (Z_ENT ==
16) ZBTBuzzUser - 50k rows (Z_ENT == 15) ZBTBuzz - ~100k rows ZBTBuzzClub - 2 rows (Z_BUZZ_ID == 123) ZBTBuzzClub - 1 row (Z_ENT == 16) 1 2 3 SELECT * from ZBTBuzz where Z_ENT = 16 AND Z_BUZZ_ID = 123;
SUBCLASSING - Z_ENT, Z_BUZZ_ID COMPOUND INDEX ZBTBuzzClub - 50k rows
(Z_ENT == 16) ZBTBuzzUser - 50k rows (Z_ENT == 15) ZBTBuzz - ~100k rows ZBTBuzzClub - 1 row (Z_ENT == 16 && Z_BUZZ_ID == 123) 1 2 SELECT * from ZBTBuzz where Z_ENT = 16 AND Z_BUZZ_ID = 123;
SUBCLASSING - Z_ENT, Z_BUZZ_ID COMPOUND INDEX ZBTBuzzClub - 50k rows
(Z_ENT == 16) ZBTBuzzUser - 50k rows (Z_ENT == 15) ZBTBuzz - ~100k rows ZBTBuzzClub - 1 row (Z_ENT == 16 && Z_BUZZ_ID == 123) 1 2 SELECT * from ZBTBuzz where Z_ENT = 16 AND Z_BUZZ_ID = 123;
HOW TO FIX?
SUBCLASSING ZBTBuzzClub - 50k rows (Z_ENT == 16) ZBTBuzzUser -
50k rows (Z_ENT == 15) ZBTBuzz - ~100k rows ZBTBuzzClub - 2 rows (Z_BUZZ_ID == 123) 1 2 for (id result in results) { if ([result isKindOfClass:[BTBuzzClub class]]) { … } } SELECT * from ZBTBuzz where Z_BUZZ_ID = 123;
IN SHORT, DON’T SUBCLASS!
MANAGE TYPES YOURSELF ZBTBuzz(Club) - 50k rows (Z_TYPE == BUZZCLUB)
ZBTBuzz(User) - 50k rows (Z_TYPE == BUZZUSER) ZBTBuzz - ~100k rows select * from ZBTBuzz where Z_TYPE = BUZZCLUB AND Z_BUZZ_ID = 123; Compound: ‣ Z_TYPE, Z_BUZZ_ID
PROFILING ON THE FLY
PROFILING ▸ -com.apple.CoreData.SQLDebug 1
PROFILING 2015-11-20 10:09:48.593 BeeTalk[3579:1652444] CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT,
t0.ZDATA, t0.ZDISPLAYINDEX, t0.ZISOUTGOING, t0.ZISWHISPER, t0.ZMEDIASTATUS, t0.ZMSGID, t0.ZREADCOUNT, t0.ZSTATUS, t0.ZTIMESTAMP, t0.ZTYPE, t0.ZWHISPERDURATION, t0.ZWHISPERSTARTTIME, t0.ZBUDDYINFO, t0.ZCHAT, t0.Z5_CHAT, t0.ZINVCHAT, t0.Z5_INVCHAT, t0.ZLASTREADCHAT, t0.Z5_LASTREADCHAT, t0.ZUSER FROM ZBTMESSAGE t0 WHERE (( t0.ZMEDIASTATUS = ? OR t0.ZMEDIASTATUS = ?) AND t0.ZTYPE = ?) 2015-11-20 10:09:48.594 BeeTalk[3579:1652444] CoreData: annotation: sql connection fetch time: 0.0002s
PROFILING + (void)load { #if defined DEBUG || defined INTRELEASE
Method original, swizzled; original = class_getInstanceMethod(self, @selector(executeFetchRequest:error:)); swizzled = class_getInstanceMethod(self, @selector(executeFetchRequest_Swizzled:error:)); method_exchangeImplementations(original, swizzled); #endif } - (NSArray *)executeFetchRequest_Swizzled:(NSFetchRequest *)request error:(NSError *__autoreleasing *)error { NSString *logFormat = [NSString stringWithFormat:@"[%@]: %@", request.entityName, request.predicate.tracerPredicate]; CFAbsoluteTime start = CFAbsoluteTimeGetCurrent(); NSArray *results = [self executeFetchRequest_Swizzled:request error:error]; CFAbsoluteTime end = CFAbsoluteTimeGetCurrent() - start; // 100ms if (end - start > 0.1) { NSLog(@"%@", logFormat); NSParameterAssert(NO); } return results; }
MIGRATION WHAT REALLY HAPPENS?
Z_METADATA - PLIST
DIFFERENT HASH? BTUSER BTUSER_BAK Rename
DIFFERENT HASH? BTUSER_BAK BTUSER Insert
DIFFERENT HASH? BTUSER_BAK BTUSER
DIFFERENT HASH? BTUSER
Z_PRIMARYKEY TABLE
Z_PRIMARYKEY TABLE
Z_ENT - ALPHABETICAL ORDER 18 | BTLINKEDCONTACT 19 | BTMESSAGE
Z_ENT - ALPHABETICAL ORDER 18 | BTLINKEDCONTACT 19 | BTMESSAGE
XX | BTMARY
Z_ENT 19 | BTMESSAGE 18 | BTLINKEDCONTACT XX | BTMARY
Z_ENT 18 | BTLINKEDCONTACT 20 | BTMESSAGE 19 | BTMARY
Z_PRIMARYKEY
HOW TO FIX?
Z_ENT 18 | BTLINKEDCONTACT 19 | BTMESSAGE 50 | BTZMARY
Z_ENT 18 | BTLINKEDCONTACT 19 | BTMESSAGE 50 | BTZMARY
Q&A