Drukowana wersja tematu

Kliknij tu, aby zobaczyć temat w orginalnym formacie

Forum PHP.pl _ MySQL _ MySQL - dodanie seryjne rekordów

Napisany przez: arpi 21.07.2019, 22:08:22

Witam
Do tej pory wszytskie zapytania do bazy wykonuje z poziomu PHP, jendak przy dużych ilościach danych zauważam problemy z wydajnością.
Chciałbym część zapytań wykonywać bezpośrednio na bazie MySQL.

Czy może ktoś wie jak zrobić poniższe zapytanie (pętle) bez zastosowania php ?

  1.  
  2. $i = 0;
  3.  
  4. for($i; $i<31262; $i++){
  5. $insert = http://www.php.net/mysql_query("INSERT INTO nazwa_tabeli (id_product, priority) values ($i, 'taki sam ciąg znaków')");
  6. http://www.php.net/echo $i.'<br>';
  7. }
  8.  


z góry wielkie dzięki

Napisany przez: viking 22.07.2019, 06:33:05

Najpierw generuj listę values potem podstaw do zapytania. Rozszerzenie mysql_ zostało dawno temu usunięte z php.

Napisany przez: arpi 23.07.2019, 09:32:35

Jeśli ma ktoś gotowy kod SQL będę zobowiązany.

Napisany przez: sazian 23.07.2019, 20:24:18

Domyślam się że viking miał na myśli coś w wym stylu

  1. $values=[];
  2. for($i=0; $i<31262; $i++){
  3. $values[]="($i, 'taki sam ciąg znaków')";
  4.  
  5. }
  6. $insert = http://www.php.net/mysql_query("INSERT INTO nazwa_tabeli (id_product, priority) values ".http://www.php.net/implode(',',$values));

chociaż przy takich ilościach rekordów i tak może to być wolne.
Ewentualnie można by się pokusić o napisanie jakiejś procedury sql która będzie "robiła pętle", istnieje szansa że będzie to trochę szybsze niż wysyłanie tak dużego zapytania
https://dev.mysql.com/doc/refman/5.7/en/while.html

Napisany przez: kreatiff 23.07.2019, 21:52:07

A spróbuj to zrobić tak. Nadal to jedno po drugim, ale w jednej transakcji i PDO:

  1. $pdo = new PDO('mysql:host=localhost;dbname=nazwa_bazy;charset=utf8', 'user', 'hasło');
  2. $pdo->beginTransaction();
  3. $q = $pdo->prepare("INSERT INTO nazwa_tabeli (id_product, priority) values (:id_product, :priority)");
  4. for ($i = 0; $i < 31262; $i++) {
  5. $q->bindValue(':id_product', $i, PDO::PARAM_INT);
  6. $q->bindValue(':priority', 'taki sam ciąg znaków', PDO::PARAM_STR);
  7. $q->execute();
  8. }
  9. $pdo->commit();


A jak ma być najszybsze (czyli jedno zapytanie z 30k+ INSERTami na raz <nie mam pojęcia, czy tyle można, w SSLite jest zdaje się limit jakiś, 500?>), to tak jak wyżej, albo jeśli 'taki sam ciąg znaków' jest wszędzie ten sam, to najpierw pododawaj same id_produkt, a dopiero później zrób update priority dla całego przedziału.

Napisany przez: arpi 25.07.2019, 10:13:38

Dziękuje za odpowiedzi, wasze rozwiązania za pomocą PHP są rzeczywiście troszkę szybsze od mojego (przykład podałem taki prosty aby był łatwy do analizy).
Jednak nie ukrywam że pytałem jak to zrobić bez PHP, czyli za pomoca samego SQL. wiem że są procedury w MySQL ale nie miałem z tym nigdy styczności, a podejrzewam ze za ich pomocą taki skrypt wykona się kilkadziesiąt razy szybciej.

Przykład: kopiowanie tabel za pomoca SQL trwa kilka sekund, z poziomu PHP import/export około minuty.

Napisany przez: nospor 25.07.2019, 10:16:44

Czyzby chodzilo ci o to
https://dev.mysql.com/doc/refman/8.0/en/load-data.html
?

Napisany przez: sazian 25.07.2019, 18:02:08

@kreatiff tylko po co pdo skoro @arpi korzysta z mysql - należały by przejść na mysqli
https://www.php.net/manual/en/mysqli.prepare.php
https://www.php.net/manual/en/mysqli.begin-transaction.php
https://www.php.net/manual/en/mysqli.commit.php

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)