UPDATE table from other table
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
Code (php)
1
2
3
4
2
3
4
CREATE TABLE tmp_' . $hdesk . ' AS
SELECT *
FROM dns_tickets
WHERE ticket_hdesk = ' . $hdeskID
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:
Code (php)
1
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 ?
Heb je al geprobeerd om bijvoorbeeld een (of meer) index(en) aan te maken voor snelle(re) lookup? Of gekeken hoe het komt dat e.e.a. traag is (aangenomen dat dat de reden is, of vanwaar dus deze wens)?
Het komt doordat de update best wel wat langer duurt.
Ik moet alle tickets updaten mbt SLA's en kosten berekenen.
Per afdeling kunnen de kosten verschillen.
In eerste instantie dmv csv, xml en xls files update ik vrijwel alle tickets al met een vaste datum, zodat ik daarna kan zien welke geupdate zijn in de live tabel, en vervolgens in de import tabel zie welke nieuw zijn.
Alle updatet tickets moet ik bijwerken mbt SLA kosten en afdelingen, daarna de tickets uit de import tabel toevoegen, en ook nog eens bijwerken, met missende gegevens.
Dit x10 met een cronjob van 5 minuten, het liefst sneller, maar helaas heeft het update script iets tijd nodig om 100 duizenden tickets te bewerken.
M'n updates zijn op basis van de ticket_id, waarvan ik verwacht dat het niet veel sneller kan dmv extra index fields.
Hierdoor lopen gebruikers ietswat vertraging op.
Het gaat maar om seconden werk, soms iets langer dan 3 seconden in totaal om alles bij te werken, maar de tabel dns_tickets raakt gelocked, en staan queries in de wacht tijdens de updates na het importeren.
Dit wil ik graag teniet doen, door per helpdesk een copy te maken van de live tickets, incl. ID, en daarin te werken tot het klaar is, en dan in 1 klap de updates te verwerken.
(de inserts gebeuren wel op de live tabel, maar dat zijn aanzienlijk minder dan de updates)
Ik verwacht dat de eindgebruikers op deze manier geen tot zeer weinig vertraging oplopen, wat frustraties en ban's zal verminderen.
Bans in de zin van, qos bans omdat ze als kippen zonder kop refresh table blijven klikken (een ajax request dat de tickets ophaald op basis van hun filter en aantallen p. pagina)
Wat ik me afvraag, is of het noodzakelijk is om alle records van de tabel in een beweging te updaten en zo regelmatig ook. Zou je kunnen volstaan met enkel van records die geraadpleegd worden een actuele/ ge-update versie te tonen. Vervolgens ‘s nachts alle records bijwerken.
Ja dit is gewenst.
Binnen een paar miljoen tickets zijn er gemiddeld vrijwel ongeveer 150.000 aanpassingen, soms meer binnen 3 minuten :-/
Ik heb trouwens dynamische waardes, maar ik weet niet of de SQL server er vrolijk van wordt als ie zelf alle berekeningen in een klap moet uitvoeren en dus zelf de records al update tijdens de import ipv uitbesteden aan php.
Ik zit er bijna aan te denken om over te gaan naar een SAP backend.
Hoewel ik niet denk dat het er veel beter op zal gaan worden.
Ik ga nog wat verder stoeien, en anders zeg ik gewoon dat ze maar ietwat geduld moeten hebben of hun verwachtingen moeten aanpassen in het FO en een nieuwe change aanvragen.
Het wordt al complexer als je over meerdere records een totaalplaatje opvraagt ('SLA afdelingskosten'?), maar het is nog steeds te doen en misschien wel efficiënter als bewerkingen die ook nog 's een UPDATE en/of INSERT met zich meebrengen.
Databases verschillen ook in snelheid. Met voor soort database werkt SAP? HANA?
Gewijzigd op 07/12/2017 10:12:56 door Nick Vledder
Nick Vledder op 07/12/2017 09:33:41:
SAP werkt doorgaans met Oracle maar kan in kleinere omgevingen ook Microsoft en HANA werken. Oracle is marktleider in SAP. In alle gevallen is het RDBMS wel bereikbaar buiten SAP maar een herkenbaar datamodel is niet echt beschikbaar. Een tabel aangemaakt met het SAP frontend is niet 1:1 terug te vinden in het RDBMSDatabases verschillen ook in snelheid. Met voor soort database werkt SAP? HANA?
Gewijzigd op 07/12/2017 11:35:02 door Aad B
Het gaat in een totaal plaatje inderdaad om miljoenen records, waarvan er gemiddeld 150.000 updates zijn in kort tijdbestek.
Het 'on the fly' toepassen van de algoritmes en berekeningen kan wel, maar het gaat niet om enkele gebruikers, en inderdaad zijn de totalen het meest van belang en het visualiseren van de data.
Uiteraard is dit nooit van ALLE tickets, maar in tijdsbestekken, en per team.
Het bedrijf waar ik werk is wereldwijd en een van de marktleiders op logistiek transport.
Deze tickets komen uit vele helpdesks, welke langzaam maar zeker wel ver gaan uitdunnen tot 1 centraal systeem (eindelijk). Maar dat betekend niet dat de tickets minder worden ;-)
Op het moment heb ik meerdere servers, p.s. draaien SQL op OutSystems
Ik ben met kleine projectjes bezig met SAP Hana en Fiori, maar .. anyways ik voel dat we afdwalen :D
Kan ik simpelweg gewoon alle kolommen en records van tabel updaten naar tabel2 op tabel1.id = tabel2.id
Zonder alle veldnamen te specificeren, jullie begrijpen wel dat dit een uitgebreid en 'levend' project is, en als ik deze query elke keer moet aanpassen als ik weer een nieuwe variable erbij krijg per ticket, dat ik rekening moet houden om ALLE queries bij te werken van alle helpdesk imports..
Gewijzigd op 07/12/2017 20:06:28 door Dennis WhoCares
@Dennis Eerlijk gezegd durf ik deze vraag niet met een ja of nee te beantwoorden, omdat ik bij deze orde van grootte (# records / velden) zelf probeer te voorkomen SQL dit soort geheugen-intensieve operaties te laten uitvoeren.
welke geheugen-intensieve operaties bedoel je precies? Gehele tabellen heen en weer kopieren ?
Momenteel doe ik de berekeningen enz gewoon in php
Gewijzigd op 08/12/2017 15:55:28 door Nick Vledder
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.
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)
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.
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:
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.Momenteel doe ik de berekeningen enz gewoon in php
Gewijzigd op 12/12/2017 11:50:48 door Aad B