Hallo allemaal,

Ik heb een script waarbij ik via jQuery een tabel aanmaak waarin ik heel snel een row kan opzoeken tussen 36.000+ andere rows.

Maar het duurt HEEEEL lang voordat het geladen is.

Weet iemand hoe ik dit kan verbeteren?


De query:
<?php

$sql = "
SELECT
ID,
client_id,
name,
contact
FROM
clients
ORDER BY
name, ID
";
?>

De tabel:
<?php
CREATE TABLE IF NOT EXISTS `clients` (
`ID` int(20) NOT NULL,
`client_id` int(20) NOT NULL,
`name` varchar(255) NOT NULL,
`street` varchar(255) NOT NULL,
`postal` varchar(255) NOT NULL,
`city` varchar(255) NOT NULL,
`country` varchar(255) NOT NULL,
`phone` varchar(255) NOT NULL,
`since` varchar(255) NOT NULL,
`changed` varchar(255) NOT NULL,
`contact` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=36085 DEFAULT CHARSET=latin1;
?>

Alvast bedankt!
Joni Fleischer op 10/06/2015 19:59:04

Ik heb het al!!!

Gewoon jSON uitpoepen :)

http://www.fleischer.nl/Grundfos/handlers/clients_processing.php

Nu gaat ie lekkah!

Bedankt !


Omdat niemand anders het vermeld, doe ik het maar even om het punt maar even duidelijk te maken.

NIEMAND heeft 36k rows nodig om wat te gaan doen. 1k resultaten is meer dan voldoende voor elk type website. En met 1k resultaten ben je zelfs gewoon slecht bezig.

Als jij denkt dat JSON jouw uitkomst is, prima en dan raad ik jouw aan om ergens hier te gaan eten.


Ik zeg er wel bij dat de database vrijwel altijd erg efficiënt is met het ophalen van data. Het verwerken daarvan zal jouw bottleneck wezen.
Niemand commentaar op veldoptimalisatie? Telefoonnummers, postcodes hebben een redelijk standaard opmaak en lengte, een stuk korter dan 255 tekens. Hier kan je ook een boel winst op behalen.
- wes - op 11/06/2015 09:26:53

Telefoonnummers, postcodes hebben een redelijk standaard opmaak en lengte, een stuk korter dan 255 tekens. Hier kan je ook een boel winst op behalen.

Bij een VARCHAR helaas niet. Als je altijd postcodes van maximaal 7 karakters opslaat, maakt het voor de performance niet uit of je daarvoor nu een VARCHAR(7) of VARCHAR(255) gebruikt. Die extra ruimte wordt gewoon niet gebruikt als daarvoor geen data is.

Wat wel helpt: als postcodes altijd precies 7 karakters zijn, kun je beter een CHAR(7) gebruiken.

Verder kan bijvoorbeeld de `country` varchar(255) naar een aparte tabel. Dan heb je voor de sleutels alleen nog een TINYINT nodig.
since en changed klinkt als datum. In dat geval lijkt me varchar niet wenselijk.
Pro forma kan je nog de engine wijzigen naar MyISAM en een FIXED recordlengte gebruiken. In sommige gevallen is dat sneller dan InnoDB. Voor de rest ben ik het met iedereen eens, behalve natuurlijk dan dat door JSON als output van PHP te kiezen de SQL query sneller uitgevoerd zou worden. Ja, de laadtijd wordt verkort. Maar de laadtijd kan NOG korter door alle 36k rijen meteen in HTML uit te voeren. Dan heb je geen 2e HTTP request, EN wordt het ondersteund op browsers zonder JavaScript (handig voor SEO).
Wat is de use case voor de oplossing van Joni?
maar 36000 rows + overhead van de html-code om het als tabel te tonen (en alle andere opmaak erbij), is een flinke hoeveelheid data.

Dat moet overgestuurd worden en vervolgens moet de browser dat omzetten in iets dat getoond moet worden.

Met een beetje pech is je browser ook nog eens een paar duizend keer bezig om de breedte van elke kolom steeds opnieuw te bepalen.

Mogelijk dat daarna jQuery snel kan zoeken, maar je laadtijd is enorm.

Daarnaast: ook jQuery krijgt direct een dataset van 36000 records te verhapstukken. Dat moet ook ergens in het javascript geheugen komen.

Ik zou het meer zoeken in een soort auto-suggest oplossing waarbij je tijdens het typen in de database gaat zoeken met ajax
Joni Fleischer op 10/06/2015 18:04:25

Hij moet juist die 36.000 rijen invoegen vanwege dat jQuery er een tabel van maakt waar je in kan zoeken.

Datatables.


Dus ik begrijp het goed als ik er vanuit ga dat je Datatables gebruikt? Dan zou ik gebruik maken van laden via Ajax, in combinatie met de optie pageLength.

Als het script dat de data ophaalt dan goed is haal je een maximaal aantal rijen op, die aan de filters voldoet van DataTables. Zie daarvoor Server side processing.
Alles is al opgelost :)


<table id="table_archive" class="display table table-striped table-bordered table-responsive" cellspacing="0" width="98%" data-page-length='18'>
  <thead>
    <tr>
      <th width="10%">Client ID</th>
      <th>Bedrijfsnaam</th>
      <th width="20%">Contact persoon</th>
      <th width="30%">E-mailadres</th>
      <th width="5%">Actie</th>
    </tr>
  </thead>
</table>



Dan de jQuery code:

var table = $('#table_archive').DataTable( {
	"language": {
		"sProcessing": "Bezig...",
		"sLengthMenu": "_MENU_ resultaten weergeven",
		"sZeroRecords": "Geen resultaten gevonden",
		"sInfo": "_START_ tot _END_ van _TOTAL_ resultaten",
		"sInfoEmpty": "Geen resultaten om weer te geven",
		"sInfoFiltered": " (gefilterd uit _MAX_ resultaten)",
		"sInfoPostFix": "",
		"sSearch": "Zoeken:",
		"sEmptyTable": "Geen resultaten aanwezig in de tabel",
		"sInfoThousands": ".",
		"sLoadingRecords": "Een moment geduld aub - bezig met laden...",
		"oPaginate": {
			"sFirst": "Eerste",
			"sLast": "Laatste",
			"sNext": "Volgende",
			"sPrevious": "Vorige"
		}
	},
	"processing": true,
	"serverSide": true,
	"ajax": "handle/clients_processing.php",
	"columnDefs": [ {
		"targets": -1,
		"data": null,
		"defaultContent": "<a class='btn btn-info btn-xs' href='#' title='Wijzigen'><span class='glyphicon glyphicon-edit' style='margin-right:0;'></span></a>"
	} ]
} );
$('#table_archive tbody').on( 'click', 'a', function () {
	var data = table.row( $(this).parents('tr') ).data();
	$(this).attr("href", "edit.php?id="+ data[ 4 ]);
});


Draait als een zonnetje!
Binnen 1 seconde 36.000+ rows uitgepoept.
Zal vast beter gecodeert kunnen worden, ben ik van overtuigd.
Joni Fleischer op 10/06/2015 19:59:04

Ik heb het al!!!

Gewoon jSON uitpoepen :)

http://www.fleischer.nl/Grundfos/handlers/clients_processing.php

Nu gaat ie lekkah!

Bedankt !

Als je dit a-synchroon uitvoert, lijkt het sneller te gaan, maar dat is het niet in de praktijk. Misschien iets minder overhead door de parsing van HTML die je eerst had.

Gewoon de boel in partjes ophalen, of als iemand een bepaald record moet zoeken een auto-suggest gebruiken die met LIKE steeds verder zoekt.

Aar!!!

Reageer ff op mijn andere forum bericht :P

Ik loop vast :'(

Reageren