Dag allemaal,

daar zijn we weer met die vervelende vragen :D

Ik heb een best wel veel velden in een 'redelijk groot' tabel.

Ik maak tijdelijke tabellen aan, om zo meervoudige aanpassingen te kunnen doen. Zonder dat de eindgebruiker die 1-20seconden hier last van heeft.

Deze data wil ik graag weer terug updaten naar de 'live' tabel.
Maar zo lui als ik ben, wil ik niet ALLE velden gaan benoemen, want het is 100% zeker dat de veldnamen hetzelfde zijn.
Ik gebruik namelijk

CREATE TABLE tmp_' . $hdesk . ' AS
                            SELECT * 
                            FROM dns_tickets 
                            WHERE ticket_hdesk = ' . $hdeskID

tickets heeft een primary key ticket_id met Auto Increment.
Ik heb wel het een en ander opgezocht en kwam eigenlijk op het volgende uit:

REPLACE INTO dns_tickets live SELECT tmp.* FROM tmp_' . $hdesk . ' tmp WHERE live.ticket_id = tmp.ticket_id

Maar hierover las ik ook weer dat deze functie eigenlijk eerst doet deleten, en dan doet inserten, klopt dit?
Is er een betere oplossing hiervoor ?
Is er uberhaupt wel een (goede) analyse gemaakt waarom het traag is? Waar zit de bottleneck? Zijn de (potentiële) probleempunten geïdentificeerd? Zou dit een kwestie kunnen zijn van serverconfiguratie (hetzij hardware, hetzij software)? En ja, mogelijk trekt je server (1 of meer?) het simpelweg niet. En als je zoveel queries hebt kunnen kleine optimalisaties potentieel heel veel winst geven.

Daarnaast (oorspronkelijke vraagstelling), met zoveel mutaties, wat voor garantie heb je dat het origineel niet gewijzigd wordt terwijl je in een kopie loopt te modderen? En als die constructie het origineel vergrendelt lijkt mij dit de vertraging alleen maar in de hand spelen omdat alles en iedereen daarop staat te wachten dan.
Hi Thomas,

ik vind dat je met zeer goede vragen komt.
Heb je enige tutorials/tips om dit uit te zoeken op een live systeem ?

Live monitoring mbt geheugen en cpu cores geven me geen indicatie dat het systeem het niet trekt.

Het orgineel wordt alleen en maar dan ook alleen door dezelfde scripts gewijzigd (op dat moment dat het script draaid wordt er wel een 'flag' gezet dat deze specifieke import voor die helpdesk al draait, dus mocht het zijn dat het een te lange operatie wordt en cronjobs over elkaar heen gaan lopen, zal dezelfde script niet draaien mits de 'flag' op 0 staat)
Ik ben geen database-expert maar ik denk dat je met een portie gezond verstand en enig inlevingsvermogen ver kunt komen. Om advies over een oplossingsrichting te kunnen geven, dat is nogal lastig omdat het, als ik het zo goed begrijp, nog niet echt duidelijk is wat de oorzaak is of oorzaken zijn (als je nu iets verandert, wat ben je dan eigenlijk aan het repareren?) en daarnaast weten we verder niets over het systeem zelf.

Is dit een pakket, of is dit zelf in elkaar gezet?
Wat voor tabeltypen gebruik je (MyISAM, InnoDB)?
PHP en MySQL versie (en type)?
Wat is je Client API library version? (zie phpinfo onder kopje mysqli)
Maak je gebruik van (foreign) keys en database-transacties?
Hoe luidt de "flow" / levensweg van een ticket?
Welke queries worden er allemaal uitgevoerd?
Zijn deze van zichzelf traag (kijk met EXPLAIN wat deze doen)?
Welke queries worden het vaakst uitgevoerd en valt hier wat winst te boeken?
Wat zegt eventuele logging van queries hierover (maar gezien de grootte van je dataset zou het loggen mogelijk de performance hiervan kunnen beïnvloeden)?
Geef je tussentijds resultaten vrij die je niet meer nodig hebt?
Is het mogelijk om (tussen)resultaten te cachen zodat deze niet elke keer opnieuw berekend hoeven te worden (hierbij moet je wel rekening houden met veranderingen in de gegevens die deze (tussen)resultaten samenstellen, je zult dan zaken opnieuw moeten berekenen)?
Je maakt ergens onderscheid tussen tickets via een datum, staat hier een index op, of wellicht zou je hier een apart veld van kunnen maken (live y/n met index)? Voor tickets die actueel zijn voeg je dan overal AND live = 1 toe ofzo, daarmee kap je al een heel groot deel van potentiële resultaten weg waar je niet meer doorheen hoeft te ploeteren. Of mogelijk zijn er meerdere statussen die een indicatie geven waar in de levensloop een ticket zich bevindt, of wellicht zijn er meerdere flags nodig (visible, deleted, whatever, ook hier geldt weer dat je dit dan in alle queries zult moeten meenemen).
Ook klinkt het gewoon alsof een of enkele tabellen VEEL te groot zijn, is het mogelijk om e.e.a. te archiveren?
Een mogelijk gevaarlijke operatie, maar heb je de tabellen ooit geOPTIMIZEd? Of gebeurt dit regelmatig? En met zo'n grote tabel is dit mogelijk een erg zware operatie...

En zo kan ik wss nog wel ff doorgaan :p.
In aansluiting op Thomas...

Je hebt al rekening gehouden met race-conditions (flag). Wat je zou kunnen doen, heel praktisch, is kijken in hoeverre je de UPDATE bewerking kan opsplitsen in kleinere batches. Vervolgens kun je onderzoeken hoe het zit met locks (ken je het verschil tussen MyISAM en InnoDB bijvoorbeeld)? Locks op records en locks op gehele tabellen. Etc., etc.
Dennis WhoCares op 08/12/2017 08:12:47

Momenteel doe ik de berekeningen enz gewoon in php
Heen en weer kopieren en mogelijke bottleneck is wellicht ook SELECT * FROM naar php het transporteren van een hele tabel naar php (array) en vervolgens weer naar de database (UPDATE INSERT REPLACE) is geheugen intensief heen en weer vliegen van tabellen. Waarom in php opgelost? Met efficiente en intelligente SQL en/of databaseprocedures met berekeningen in de database kan je zonder php enorm veel sneller resultaat bereiken. Het heen en weer schuiven van data tussen php en MySQL is zeer tijdrovend en onnodig.

Reageren