Ik ben op dit moment bezig een grote hoeveelheid data te laden in een test;
het gaat om 3 blokken, van ongeveer 2M items. Daarnaast heb ik data die per item uit de 2M items, referenties naar andere items bevat. Dit zijn ongeveer 25 referenties per item (totaal dus 50M koppelingen per blok). Daarnaast zijn er per item actoren, ongeveer 5 per item (dus 10M per blok). In werkelijkheid is het iets complexer dan ik hier beschrijf, maar om het simpel te houden heb ik 3 tabellen aangemaakt;
De data komt ergens anders vandaan, en ik wil graag wel de mogelijkheid hebben om terug te kunnen koppelen naar de bron; daarom moet ik de IDs aanhouden uit de bron, en dat past niet in een INT, vandaar de BIGINT.
De data laad ik uit flat files die ik heb gegenereerd door middel van een LOAD DATA LOCAL INFILE IGNORE statement. Per tabel is er 1 flatfile die in principe direct de database in kan, dus 2M regels in items.txt, 50M regels in item_referentie.txt etc.
Voor het eerste blok (draait in een loopje in PHP, na elkaar) gaat het nog redelijk; dit zijn de loadtimes voor blok1 vs blok2 vs blok3; note dat hij voor blok1 met een schone DB begint, de andere blokken komen bovenop de data die daarvoor is geladen.
*deze LOAD DATA draait nog op dit moment.
Zoals je kunt zien is de load time in het 2e en 3e blok gigantisch ontploft. Ik heb het vermoeden dat ik tegen de redelijkheid van een index size aanloop. Moet ik deze data dan maar op gaan splitsen in meerdere tabellen per blok? want dit zijn voor een test 3 blokken, ik heb er straks 14...
Zoals je ook kunt zien gebruik ik MyISAM; ik begon met InnoDB, maar dat was met de items tabel al traag. InnoDB deed dezelfde query zonder index 2x zo langzaam als MyISAM met een PK. Met unique key was InnoDB zelfs 20x trager over dezelfde insert in MyISAM. Maar misschien blijft het bij InnoDB constanter ipv de exponentiele groei in laadtijd met MyISAM? of vinden jullie dat ik uberhaupt van MySQL bij zoiets moet afstappen? want kan ik straks over die index nog wel een redelijke query draaien (bv top uitrekenen van het aantal referenties per actor in een deelverzameling van items)?
het gaat om 3 blokken, van ongeveer 2M items. Daarnaast heb ik data die per item uit de 2M items, referenties naar andere items bevat. Dit zijn ongeveer 25 referenties per item (totaal dus 50M koppelingen per blok). Daarnaast zijn er per item actoren, ongeveer 5 per item (dus 10M per blok). In werkelijkheid is het iets complexer dan ik hier beschrijf, maar om het simpel te houden heb ik 3 tabellen aangemaakt;
SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| CREATE TABLE IF NOT EXISTS `item` ( `id` bigint(20) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; CREATE TABLE IF NOT EXISTS `item_actor` ( `item_id` bigint(20) NOT NULL, `actor_id` bigint(20) NOT NULL, PRIMARY KEY (`item_id`,`actor_id`), KEY `actor_id` (`actor_id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; CREATE TABLE IF NOT EXISTS `item_referenties` ( `item_id` bigint(20) NOT NULL, `referentie_item_id` bigint(20) NOT NULL, PRIMARY KEY (`item_id`,`referentie_item_id`), KEY `referentie_item_id` (`referentie_item_id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; |
De data komt ergens anders vandaan, en ik wil graag wel de mogelijkheid hebben om terug te kunnen koppelen naar de bron; daarom moet ik de IDs aanhouden uit de bron, en dat past niet in een INT, vandaar de BIGINT.
De data laad ik uit flat files die ik heb gegenereerd door middel van een LOAD DATA LOCAL INFILE IGNORE statement. Per tabel is er 1 flatfile die in principe direct de database in kan, dus 2M regels in items.txt, 50M regels in item_referentie.txt etc.
Voor het eerste blok (draait in een loopje in PHP, na elkaar) gaat het nog redelijk; dit zijn de loadtimes voor blok1 vs blok2 vs blok3; note dat hij voor blok1 met een schone DB begint, de andere blokken komen bovenop de data die daarvoor is geladen.
tabel | laadtijd blok1 | laadtijd blok2 | laadtijd blok3 |
item | 48.89s | 3m 6.07s | 6m 42.78s |
item_actor | 2m 51.70s | 6h 21m 49.17s | 9h 36m 32.62s |
item_referentie | 14m 40.05s | 34h 51m 50.45s | 18+ hours and counting* |
Zoals je kunt zien is de load time in het 2e en 3e blok gigantisch ontploft. Ik heb het vermoeden dat ik tegen de redelijkheid van een index size aanloop. Moet ik deze data dan maar op gaan splitsen in meerdere tabellen per blok? want dit zijn voor een test 3 blokken, ik heb er straks 14...
Zoals je ook kunt zien gebruik ik MyISAM; ik begon met InnoDB, maar dat was met de items tabel al traag. InnoDB deed dezelfde query zonder index 2x zo langzaam als MyISAM met een PK. Met unique key was InnoDB zelfs 20x trager over dezelfde insert in MyISAM. Maar misschien blijft het bij InnoDB constanter ipv de exponentiele groei in laadtijd met MyISAM? of vinden jullie dat ik uberhaupt van MySQL bij zoiets moet afstappen? want kan ik straks over die index nog wel een redelijke query draaien (bv top uitrekenen van het aantal referenties per actor in een deelverzameling van items)?