Un caso típico en el desarrollo web con PHP y MySQL es la funcionalidad de paginar resultados, si bien no es algo dificil muchos desperdician la potencialidad y malgastan los recursos de MySQL.
Para paginar resultados necesitamos saber 3 valores:
Número de Página: este valor lo pide el usuario, asi que es fácil obtenerlo.
Total de registros por página: normalmente lo define el programador con una constante
Total de registros: necesitamos saber el total de registros para poder crear la cantidad de enlaces necesarios por página.
Donde se desperdicia el potencial y malgasta recurso de MySQL normalmente es en el 3 valor. Pues muchos ejecutan una consulta con LIMIT y otra consulta con un COUNT sin el LIMIT. Y es allí donde es el error, ya que MySQL ofrece las funciones: SQL_CALC_FOUND_ROWS y FOUND_ROWS.
SQL_CALC_FOUND_ROWS: calcula el número de resultados de una consulta sin LIMIT.
FOUND_ROWS: obtiene el resultado del último SQL_CALC_FOUND_ROWS ejecutados.
Aunque con estas funciones debemos igual ejecutar dos consultas, el calculo y tiempo de respuesta es mucho más rápido que haciéndolo con COUNT.
En la configuración de PHP (php.ini) el valor mysql.trace_mode debe estar en Off. Si está en On por cada consulta que se haga a mysql se ejecuta un explain y esto hace sql_calc_found_rows inutil, por ende, found_rows siempre retornara 0. Este valor normalmente está en off, pero cabe la advertencia.
Sobretodo por lo de SQL_CALC_FOUND_ROWS, muchos lo desconocen.
saludos Por:Dano-blog
Gracias Maikel!, no tenia idea de que existían esas funciones. A aplicar de ahora en adelante. Por:-george-
Excelente Aporte... Deberíamos ir conociendo mas las consultas de MySql a solo las funciones de PHP.. Excelente Hermano Por:JoseAlejandro_Realza
Si Anonimo-blog, tiene razon, asi es. Por:toffman-blog
aunque no me andan los links a mi. porque sera?? osea los muestra pero en la url queda "?pag=" sin valores Por:Toffman-blog
ha si lo que pasa es que no le pasa la variable $i; asi quedaria bien -> $links[] = "<a href="?pag=$i">$i</a>"; Por:toffman-blog
Cambiar
Código :
$offset = ($pag-1) * $maxPag;
por
Código :
$offset = ($pag-1) * $limit;
Cambiar:
Código :
$links[] = "<a href=\"?pag=\">$i</a>";
por
Código :
$links[] = "<a href=\"?pag=$i\">$i</a>";
Es lo que pasa por escribir un tipo a las 3am...
saludos Por:Maikel
maki podes explicar para que es SQL_CALC_FOUND_ROWS, Grcias Por:jpcw-blog
SQL_CALC_FOUND_ROWS: calcula el número de resultados de una consulta sin LIMIT. FOUND_ROWS: obtiene el resultado del último SQL_CALC_FOUND_ROWS ejecutados;
saludos Por:Maikel
Gracias por compartir es tip Maikel Por:psycho-vnz
muy buen aporte =)
cuando tenga tiempo lo pruebo Por:Jinik
Interesante aporte Maikel, justamente estaba necesitando algo similar... Por:Blackdragon
Ya está el tip actualizado con los cambios sugeridos por Maikel. Por:Freddie
yo "paginó" con DataTables (table plug-in for jQuery)
lo recomiendo, te coloca casilla de busqueda, numero de registros por página (5,10, 25, 100) Por:Calviche82-blog
Tiempo trabajando con MySQL y no conocía el SQL_CALC_FOUND_ROWS, uno siempre aprende algo nuevo. Excelente tip como siempre Por:Aoyama
Maikel
Hola man!!, Bueno yo que soy un poco compulsivo con los errores esta línea te puede producir un warning
Maikel :
Código :
$pag = (int) $_GET["pag"];
Si no se a enviado la variable pag, ya sea por inicialización de la página o por que el usuario la borro. Yo aconsejaría verificarla algo como esto>
Código :
if (isset($_GET['pag'])){
$pag = (int) $_GET["pag"];
if ($pag < 1){
$pag = 1;
}
}else{
$pag = 1;
}
También cabría notar, aunque no se si no lo vi, que pasaría si el usuario manda un valor de página superior a las páginas que se pueden generar, es decir, si el usuario manda pag=100, y solo se pueden generar 5 páginas, se generaria un error en la consulta, pero este se puede arreglar fácilmente comparando que la página enviada no sea mayor a las páginas que se generan de la consulta. Buena esas son mis sugerencias
Si no se a enviado la variable pag, ya sea por inicialización de la página o por que el usuario la borro. Yo aconsejaría verificarla algo como esto>
Código :
if (isset($_GET['pag'])){
$pag = (int) $_GET["pag"];
if ($pag < 1){
$pag = 1;
}
}else{
$pag = 1;
}
Que tal así?
Código :
$pag = (int) @$_GET["pag"];
y me dejas lo demás como está
esutoraiki :
También cabría notar, aunque no se si no lo vi, que pasaría si el usuario manda un valor de página superior a las páginas que se pueden generar, es decir, si el usuario manda pag=100, y solo se pueden generar 5 páginas, se generaria un error en la consulta, pero este se puede arreglar fácilmente comparando que la página enviada no sea mayor a las páginas que se generan de la consulta. Buena esas son mis sugerencias
La consulta no generará error, simplemente no retornará registros. Por:Maikel
Para ser más quisquillosos aún!
Código :
$pag = ( isset($_GET["pag"]) and ($_GET["pag"] > 0) and ($_GET["pag"] <= $totalPag) ? $pag = $_GET["pag"] : $pag = 1;
Se podría "comprobar" más el dato, is_int, etc... Obviamente sería mucho más entendible con un If común en vez del ternario.
El error o no de si está seteada $_GET["pag"] dependería de la configuración de PHP. Por lo general los hostings compartidos y algunos que no le ponen enfasís en el detalle no tirarían error, un dedicado masomenos bueno seguramente.
Pero bueno hablando del tip, muy bueno! nunca lo había escuchado/leído el CALC ROWS, grax por el aporte Maikel!. Por:raxiro
Hola man esta bueno esto `, pero me genera un problema es que el paginado sale impreso completo osea un link para cada pagina
que hago Por:malditosan-blog
joda men me le quito el sombrero, este codigo si me sirvio, lo felicito Por:jhonny-blog
Hola . Quiero decir que inclui el código y sin embargo, a pesar de mostrar la tabla con los links a las distintas paginas, siempre, en cada pagina, me tira todos los registros (puse 50 para probar).
ASi que quería saber porque no puedo limitarlos a 5.
Luego si, la tabla marca 10 paginas (correspondientes a 5*10=50 registros) o sea que esa parte esta ok,
¿Se puede solucionar?
Gracias! Por:Oscar-blog
me sale este error Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in /var/www/html/php/paginacion/paginacion.php on line 28
el problema es id_categoria=$_GET[id_categoria]
pero lo quiero ordenar por categoria
$sql = "SELECT SQL_CALC_FOUND_ROWS nombre_categoria,nombre_producto,ruta_foto_grande,ruta_foto_pequena,descripcion_producto FROM producto,foto,categoria where id_foto=producto_id_foto and id_categoria=producto_id_categoria and id_categoria=$_GET[id_categoria] group by nombre_producto LIMIT $offset, $limit";
$sqlTotal = "SELECT FOUND_ROWS() as total";
Holas amigo Bueno soyy novato en esto asi que sin animos de querer molestarlos, me podrian decir cuales serian los campos que deberia cambiar de acuerdo a mi bd X) Por:Carlos-blog