# Grosse Datenmenge mit SELECT, Artikel über SW API erstellen

**URL:** https://forum.shopware.com/t/grosse-datenmenge-mit-select-artikel-uber-sw-api-erstellen/47091
**Category:** Programmierung
**Created:** [24. Juli 2017 um 15:43 UTC](https://forum.shopware.com/t/grosse-datenmenge-mit-select-artikel-uber-sw-api-erstellen/47091 "2017-07-24T15:43:29Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![hagmann.io](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.shopware.com/hagmann.io/32/7795_2.png) [@hagmann.io](https://forum.shopware.com/u/hagmann.io)
#### Post date: [24. Juli 2017 um 15:43 UTC](https://forum.shopware.com/t/grosse-datenmenge-mit-select-artikel-uber-sw-api-erstellen/47091/1 "2017-07-24T15:43:29Z")

</div>

Guten Tag,

- Ich habe ein eigenes Datenmodell und eine dazugehörige MySQL Tabelle erstellt (h\_Article).
- Diese Daten sollen über den SELECT Query später noch gefiltert werden und per Shopware Article API Manager gespeichert werden.

&nbsp;

Das funktioniert soweit, aber die Aktion bricht nach ca. 2500 gespeicherten Artikeln ab (insgesamt ca. 240’000). Womöglich weil das Memory vollgelaufen ist. Eher kein Timeout, da der Task ca. \>10 Minuten gelaufen ist.

&nbsp;

```
 $resource = new Client(); $sql = "SELECT \* from h\_Article"; $result = Shopware()-\>Db()-\>query($sql); foreach ($result as $article) { $resource-\>addArticleInformation($article); } 

```

&nbsp;

Der Methode addArticleInformation werden die einzelnen Artikel aus dem SQL Result übergeben und von da aus werden diese über die SW API gespeichert.  
&nbsp;

Wie kann der Code optimiert werden, dass beispielsweise Zeile für Zeile selektiert und importiert wird, um das Memory zu schonen?

&nbsp;

&nbsp;

EDIT: Soeben habe ich gerade folgende Errormessage erhalten, es scheint also defintiiv das Memory-Limit zu sein.

**Fatal error** : Allowed memory size of 134217728 bytes exhausted (tried to allocate 4536001 bytes) in&nbsp; **C:\htdocs\incocare.ch\engine\Shopware\Components\Thumbnail\Generator\Basic.php** &nbsp;on line&nbsp; **221**

---

<div class="post-metadata">

### Author: ![gearsdigital](https://avatars.discourse-cdn.com/v4/letter/g/ed655f/32.png) [@gearsdigital](https://forum.shopware.com/u/gearsdigital)
#### Post date: [24. Juli 2017 um 16:16 UTC](https://forum.shopware.com/t/grosse-datenmenge-mit-select-artikel-uber-sw-api-erstellen/47091/2 "2017-07-24T16:16:15Z")

</div>

Ich würde das über [Pages Queries](https://stackoverflow.com/questions/3799193/mysql-data-best-way-to-implement-paging) lösen und die Daten „Chunkweise“ rüber schaufeln.

---

<div class="post-metadata">

### Author: ![hagmann.io](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.shopware.com/hagmann.io/32/7795_2.png) [@hagmann.io](https://forum.shopware.com/u/hagmann.io)
#### Post date: [24. Juli 2017 um 16:28 UTC](https://forum.shopware.com/t/grosse-datenmenge-mit-select-artikel-uber-sw-api-erstellen/47091/3 "2017-07-24T16:28:12Z")

</div>

Besten Dank für den Tipp. Ich habe bereits an die Pagination direkt im SQL Query gedacht. Diese habe ich jetzt mal implementiert:

&nbsp;

```
 $limit = 20; $offset = 0; for ($i = 0; $i \< 240000000; $i++) { $sql = "SELECT hci\_article.pharmacode, hci\_article.dscrpackd, hci\_article.dt, hci\_article.dscrpackf, hci\_article.dscrd, hci\_article.gtin, hci\_article.artpri\_exf, hci\_article.artpri\_pub, hci\_article.vat, hci\_article.weight, hci\_article.img2, hci\_company.nams, hci\_company.prtno, hci\_product.smcat, hci\_kompendium\_product.monid, hci\_compendium.content, hci\_product.prdno, hci\_product.bnamd, hci\_article.width, hci\_article.height, hci\_article.depth, hci\_product.smcat, hci\_article.qtyud, hci\_article.salecd FROM hci\_article LEFT JOIN hci\_company ON hci\_article.artcomp\_h = hci\_company.prtno LEFT JOIN hci\_product ON hci\_article.prdno = hci\_product.prdno LEFT JOIN hci\_kompendium\_product ON hci\_product.prdno = hci\_kompendium\_product.prdno LEFT JOIN hci\_compendium ON hci\_compendium.monid = hci\_kompendium\_product.monid WHERE 1=1 AND hci\_product.del = FALSE AND hci\_article.salecd='N' AND (hci\_product.smcat='C' OR hci\_product.smcat='D' OR hci\_product.smcat='E') AND hci\_compendium.monidlang LIKE '%DE' LIMIT " . $limit . " OFFSET " . $offset; $result = Shopware()-\>Db()-\>query($sql); foreach ($result as $article) { $resource-\>addArticleInformation($article); } $offset = $offset + 20; $pluginLogger-\>info('Batch ' . $offset . ' - erfolgreich importiert.'); }

```

&nbsp;

Leider bricht der Import bei jeweils ca. 2500 Artikeln ab, ich kann aber nicht nachvollziehen warum das passiert.

---

<div class="post-metadata">

### Author: ![derwunner](https://avatars.discourse-cdn.com/v4/letter/d/e5b9ba/32.png) [@derwunner](https://forum.shopware.com/u/derwunner)
#### Post date: [25. Juli 2017 um 10:10 UTC](https://forum.shopware.com/t/grosse-datenmenge-mit-select-artikel-uber-sw-api-erstellen/47091/4 "2017-07-25T10:10:48Z")

</div>

> [@hagmann.io schrieb:](https://forum.shopware.com/profile/22427/hagmann.io "hagmann.io")
> 
> Besten Dank für den Tipp. Ich habe bereits an die Pagination direkt im SQL Query gedacht. Diese habe ich jetzt mal implementiert:
> 
> &nbsp;
> 
> $limit = 20; $offset = 0; for ($i = 0; $i \< 240000000; $i++) { $sql = "SELECT hci\_article.pharmacode, hci\_article.dscrpackd, hci\_article.dt, hci\_article.dscrpackf, hci\_article.dscrd, hci\_article.gtin, hci\_article.artpri\_exf, hci\_article.artpri\_pub, hci\_article.vat, hci\_article.weight, hci\_article.img2, hci\_company.nams, hci\_company.prtno, hci\_product.smcat, hci\_kompendium\_product.monid, hci\_compendium.content, hci\_product.prdno, hci\_product.bnamd, hci\_article.width, hci\_article.height, hci\_article.depth, hci\_product.smcat, hci\_article.qtyud, hci\_article.salecd FROM hci\_article LEFT JOIN hci\_company ON hci\_article.artcomp\_h = hci\_company.prtno LEFT JOIN hci\_product ON hci\_article.prdno = hci\_product.prdno LEFT JOIN hci\_kompendium\_product ON hci\_product.prdno = hci\_kompendium\_product.prdno LEFT JOIN hci\_compendium ON hci\_compendium.monid = hci\_kompendium\_product.monid WHERE 1=1 AND hci\_product.del = FALSE AND hci\_article.salecd=‚N‘ AND (hci\_product.smcat=‚C‘ OR hci\_product.smcat=‚D‘ OR hci\_product.smcat=‚E‘) AND hci\_compendium.monidlang LIKE ‚%DE‘ LIMIT " . $limit . " OFFSET " . $offset; $result = Shopware()-\>Db()-\>query($sql); foreach ($result as $article) { $resource-\>addArticleInformation($article); } $offset = $offset + 20; $pluginLogger-\>info(‚Batch ’ . $offset . ’ - erfolgreich importiert.‘); }
> 
> &nbsp;
> 
> Leider bricht der Import bei jeweils ca. 2500 Artikeln ab, ich kann aber nicht nachvollziehen warum das passiert.

Ja klar, weil Deine for Schleife auch nicht besser ist. Was Du suchst / brauchst ist das&nbsp;Iterator-Verfahren. Und&nbsp;dieses erreichst Du entweder über eine foreach Schleife, oder&nbsp;mit der sogenannten PDO Cursor fetch Methode.

Bei ein for Schleife fängt er jedes mal wieder bei Array Index 0 das Suchen an, während er beim Iterator Verfahren einfach vom letzten auf den nächsten Array Index springt (wie bei fopen und fgets bei einer simplen Textdatei).&nbsp;Das ist gerade bei großen Datenmengen interessant, also eben in Deinem Fall.

Hol dir am besten über den DBAL Service (Shopware Container) das PDO Objekt und führe Deinen Query mittels PDO Cursor fetch Zeile für Zeile aus. Siehe dazu am besten Beispiel #2 in der PHP Doku, besser hätte ich es auch nicht erklären können. Den Code kannst du 1:1 so übernehmen (davor kommt logischweise noch der Service Abruf für das PDO Objekt):&nbsp;[PHP: PDOStatement::fetch - Manual](http://php.net/manual/de/pdostatement.fetch.php)
