Er wordt met data_seek gewerkt in deze code maar dat is wat mij betreft een verkeerde aanpak. Probleem is dat je eerst ALLE ( meer dan 1 miljoen misschien ? ) records laat klaarzetten en er dan maar tien raadpleegt. Zoals Ariën aangeeft zou je met een query met een LIMIT statement moeten werken.
[size=xsmall]Toevoeging op 29/01/2018 21:03:18:[/size]
En sorry dat ik het zeg maar hoe lang ga je met alles door elkaar werken? probeer PHP van HTML te scheiden en binnen PHP functionaliteiten van elkaar te scheiden. Je code wordt zo al snel een onoverzichtelijke bos spaghetti.
het gaat om 20 zoekopdrachten. Als het qua opbouw niets is, dan dank ik jullie voor jullie hulp en ga ik proberen om een en ander opnieuw te programmeren.
Als je straks meerdere lijsten wilt met paginanavigatie, dan wil je deze lappen code niet steeds herhalen.
Ook hier is de DRY-methode van toepassing:
'Don't Repeat Yourself'.
Dus deel de functies op in 'functions' of een 'class'.
Verder wil je met LIMIT niet steeds de eerste of de laatste items hebben, lijkt mij. Dus moet je steeds uit je aantallen records steeds een greep halen met bijv. 20 items.
- Je bepaalt hoeveel resultaten je per pagina wilt tonen. Bijvoorbeeld 10.
- Je voert een query uit die enkel het aantal rijen telt. Bijvoorbeeld:
SELECT COUNT(*) FROM strips
Stel dat dit er 125 zijn. Je kunt dan met een simpel rekensommetje uitrekenen hoeveel pagina's met resultaten je kunt tonen:
<?php
$results_per_page = 10;
$pages = ceil($rows / $results_per_page); // 125 / 10 afgerond naar boven = 13.
?>
- Vervolgens moet je bepalen op welke pagina we gebleven zijn:
<?php
$currentpage = 1;
// even onnozelheden er uit filteren:
if($currentpage < 1 || $currentpage > $pages) {
$currentpage = 1;
}
?>
- En nu kun je de tweede query in elkaar sleutelen:
<?php
$startrow = ($currentpage -1) * $results_per_page; // bijv pagina 3: 3-1 = 2 * 10 = 20. (laat rij 21 t/m 30 zien).
$query = "SELECT * FROM strips ORDER BY id LIMIT $startrow, $results_per_page";
?>
MySQL heeft een voorziening waarmee je een LIMIT-query kunt "flaggen" waarmee je aangeeft dat je ook geïnteresseerd bent in het totaal aantal resultaten, dus hoeveel resultaten dezelfde query zou opleveren als deze zonder de LIMIT-clause zou worden uitgevoerd.
Dit doe je als volgt:
<?php
// de LIMIT-query
$sql = "SELECT SQL_CALC_FOUND_ROWS <de rest van je query> LIMIT x,y";
// voer hier je query uit...
// ...
// ... en direct hierna
$sql = "SELECT FOUND_ROWS()";
// deze tweede query geeft het totaal aantal resultaten van de LIMIT-query, maar dan zonder de LIMIT
// ...
?>
Mja dat klopt, en dat blijft natuurlijk een beetje koffiedik kijken. Maar omdat het een specifiek MySQL-ding is zou je je zo kunnen voorstellen dat er ergens toch wel wat winst meegepakt zou kunnen worden. Het kan in ieder geval geen kwaad lijkt mij.
Zoals daar wordt aangehaald spelen indexes enzo (en aantal records, betrokken tabellen etc.) natuurlijk ook een rol.
Maar als het redelijk standaard queries zijn dan is dit natuurlijk interessant voor het verder automatiseren/standaardiseren van gepagineerde data.
En bij twijfel: gewoon benchmarken.
EDIT: dat soort (reacties op dat soort) topics neem ik altijd met een korrel zout, er heerst vaak een hoop verwarring, en soms worden verkeerde oorzaken voor traagheid (onterecht) toegeschreven aan dit soort constructies. De verwarring is dan natuurlijk compleet. En soms worden dus compleet idiote datasets/constructies verzonnen om dit soort dingen in een kwaad daglicht te stellen. Wat dat betreft: gewoon alles uitproberen en het goede behouden / meten is weten. Zou niet de eerste keer zijn dat iemand zegt "ik gebruik <X> niet want <verkeerde/ongefundeerde redenatie>".
Er kunnen inderdaad een aantal kanttekeningen geplaatst worden bij dit soort berichten. Ook moeten we ons realiseren dat dit topic uit 2016 stamt en er misschien in tussentijd al performance updates doorgevoerd zijn.
Uit de tekst kun je ook opmaken dat het indexeren van de juiste kolommen erg belangrijk is maar dat is iets dat we eigenlijk al weten.