Als ik truncate table GROTE_TABEL doe, dan duurt het jaren, lijkt mij gewoon dat mysq dit niet aankan
Ik heb het zojuist even geprobeerd op een oude tabel die ik zelf hier nog had rondzwerven. Tabel was 350 GB groot en had ruim 3,2 miljard records. De truncate duurde 9,52 seconden. Een select count(*) van die tabel (vóór het truncaten ;-)) was in 0,00 seconden klaar.
Overigens was dit op een fysieke server. Ik heb nog een MariaDB op een VPS draaien, maar daar heb ik geen tabellen die ik ongestraft kan truncaten. Heb daar wel een tabel van ruim 188 miljoen records waar ik een select count(*) op kan doen, en die komt ook in 0,00 seconden terug met een antwoord. Op mijn VPS had ik de afgelopen maand van de 123 miljoen uitgevoerde queries er slechts 143 die langer dan 5 seconden duurden. De tabelgrootte is dus niet per se bepalend voor de duur van je queries.
Ik vermoed dus ook (het is al vaker genoemd) dat je ergens een tuning-probleempje hebt. Je zou eens een script als https://launchpad.net/mysql-tuning-primer kunnen gebruiken om te kijken of er ergens pijnpunten zitten. Het is een oud script (uit 2011) maar ik heb er al verschillende servers goed mee kunnen tunen. Een ander script dat goede adviezen geeft (en actiever wordt ontwikkeld) is http://mysqltuner.com/
Klopt trouwens de index op prijs/productUrl/verzend_tijd/verzend_kosten? Ik kan er zelf in ieder geval geen situatie bij bedenken waarin die nodig/nuttig zou kunnen zijn.
winkel_id klinkt als een foreign key naar een tabel met winkels. Ik zie daar geen FK relatie en/of index?
het is ook een int(9), terwijl id van deze tabel een int(11) is. Wil je een relatie tussen tabellen leggen, moeten die wel gelijk zijn. Als je een int(11) op deze tabel hebben, verwacht ik dat ook op je winkel tabel. (en dus ook voor winke_id).
EAN: dat is geen getal Dat is een string bestaande uit cijfers. Wil je niet dat voorloopnullen verdwijnen, dan geen int gebruiken. VARCHAR...
Bedragen gedragen zich het best als DECIMAL(10, 2) en niet als double.
producturl: een url van 1000 tekens is al extreem. Maar in TEXT kun je 64K tekens kwijt. (overkill?)
verzend_tijd: een datetime misschien? MAar wat sla je op als je 222 tekens nodig kunt hebben?
Wil je een relatie tussen tabellen leggen, moeten die wel gelijk zijn.
En om relaties aan te kunnen leggen en transacties te kunnen gebruiken kun je beter de InnoDB engine gebruiken (is misschien zelfs nog steeds verplicht / andere engines genieten deze ondersteuning mogelijk nog steeds niet), dus dat spul is waarschijnlijk allemaal MyISAM.
Als je echt relationele databases wilt bouwen, en geen tabellen die als los zand aan elkaar hangen, dan is InnoDB eigenlijk de enige juiste keuze bij mijn weten.
verzend_tijd: een datetime misschien? MAar wat sla je op als je 222 tekens nodig kunt hebben?
Ik vermoed (wilde gok) dat de verzend_tijd niet zozeer een tijdstip is waarop het product is verstuurd, maar eerder een indicatie van de levertijd (met een niet ideaal gekozen veldnaam). Daar zou je dus iets in opslaan als "drie dagen" of "volgende dag, indien besteld voor 22:00 op werkdagen". Met een beetje creativiteit kun je dan best richting de 200 tekens komen. Maar ook in dat geval kun je nog wel normalisatie op dat veld toepassen.
Voor zover ik weet, is het verschil tussen int(9) en int(11) niet relevant bij het leggen van relaties tussen tabellen. Een int wordt gewoon opgeslagen als 4 bytes en het getal tussen haakjes is alleen voor presentatiedoeleinden (en dan vooral wanneer het veld 'zerofill' is). In het kader van consistentie is het uiteraard wel aan te bevelen e.e.a. gelijk te houden.
Het is inderdaad wat overkill om een url als text-veld op te slaan, maar ik heb in de praktijk wel urls gezien die langer dan 1000 tekens waren. Om de rijgrootte niet al teveel de spuigaten uit te laten lopen zou je die url dan in een text-veld kunnen zetten.
Thomas van den Heuvel op 20/06/2019 19:42:24
dus dat spul is waarschijnlijk allemaal MyISAM.
Als ik naar de indexdefinities kijk, zie ik een index op de eerste 767 bytes van de kolom productUrl. Dat suggereert InnoDB (met row format 'redundant' of 'compact'). By MyISAM is die limiet 1000 bytes en die 767 bytes is dermate specifiek dat ik niet denk dat iemand die spontaan zelf invoert.