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
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Sing Jie Lee
November 20, 2015
Technology
44
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
61
Sprite Kit
singjie
0
64
SiriKit
singjie
0
210
React Native
singjie
1
92
Arduino
singjie
0
45
Software Engineering
singjie
0
61
Amazon Echo and Home Integration
singjie
0
110
CS3216 Garena Project X
singjie
0
56
Life
singjie
0
44
Other Decks in Technology
See All in Technology
制約理論(ToC)入門 2026版
recruitengineers
PRO
8
2.2k
グローバル基準のSREは、運用現場でどう機能したか:成熟度アセスメントの実践 / SRE NEXT 2026
sorawatanabe
0
220
ホームラボ紹介
y_sera15
0
160
Goでデータパイプラインを作ろう
sansantech
PRO
1
440
カートの信頼性を担保するWireMockを使ったe2eテスト
ykagano
0
250
攻撃と防御で学ぶAI時代のプロダクトセキュリティ演習
recruitengineers
PRO
9
2.7k
Software Supply Chain Attackからクラウド環境を守るためにできること
lhazy
2
260
修正PRを食べてレビュースキルが賢くなる:Claude Codeによる自己改善サイクル
yuyaumetsu
6
1.5k
つくって納得、つかって実感! 大規模言語モデルことはじめ ver2.0
recruitengineers
PRO
4
1.6k
『三匹の子ぶた』から学ぶネットワークセキュリティの昔と今 / Network Security: Then and Now Through the Lens of The Three Little Pigs
nttcom
1
1.8k
まちスペース®とデジタルツインと「まちづくり」
hiro_ogi
0
110
20260804_Q4AzureUpdateBite_FabricDataAgentの精度を高める設計.pdf
matayuuu
1
130
Featured
See All Featured
How to Think Like a Performance Engineer
csswizardry
28
2.7k
Un-Boring Meetings
codingconduct
0
380
Believing is Seeing
oripsolob
1
190
Facilitating Awesome Meetings
lara
57
7.1k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
630
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
380
Thoughts on Productivity
jonyablonski
76
5.3k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
230
23k
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
370
Paper Plane
katiecoart
PRO
2
53k
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
63
45k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2.1k
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