Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Bases de datos > MySQL
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 03-04-2006
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
¿Qué número de consultas a MySQL podrían considerarse excesivas?

Hola,

Seguramente pregunto una estupidez como la casa de la alcaldesa de Marbella de grande. Pero, no me resisto a ello, por ver si no fuera del todo tan tonto como me parece incluso a mí. Al grano. ¿Existe un número de consultas a MySQL que pudiera considerarse excesivo, que diera qué pensar sobre cómo se están haciendo las cosas (de mal)?

Pongo en situación. Documento Web escrito en PHP que realiza una serie de consultas a una base de datos MySQL con el fin de recoger determinada información que se presente presentar al usuario. Está claro, me parece, que dependerá de qué se vaya a mostrar al usuario, pero, supongamos que al cabo se hacen, qué sé yo,... 100 consultas a la base de datos para conformar únicamente el documento que nos ocupa.

¿Podrían considerarse excesivas, teniendo en cuenta que se trata de un documento al que puden acceder además varios usuarios al mismo tiempo o a intervalos más o menos regulares? ¿Habría que plantearse cómo es que son necesarias "tantas" consultas? ¿Es, por el contrario, un número "normal" de consultas? ¿Queda lejos, todavía, de lo que podría considerarse excesivo? ¿Hay algún número de consultas descaradamente excesivo?

Bueno. No os agobio más. Gracias de antemano por vuestras respuestas.
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #2  
Antiguo 03-04-2006
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
¿¡¡¡¡¡¡¡¡100!!!!!!!!? ¡Pero si más de tres ya me parce un exceso! Desde luego que esto va a afectar el rendimiento de tu página. Quizá si das un poco más de información acerca de lo que haces podamos dar alguna alternativa, no sé, en una de esas y si son necesarias para lo que estés haciendo, pero da más la impresión de que te hacen falta algunos JOINS para armar una sola consulta. Y aún así, no imagino qué clase de estructura podrían tener tus datos para requerir tal cantidad de consultas.

// Saludos

Última edición por roman fecha: 03-04-2006 a las 19:26:18. Razón: Me faltaron una cuantas caritas de sorpresa y signos de admiración
Responder Con Cita
  #3  
Antiguo 03-04-2006
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.044
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Estoy conforme con Roman, yo diría que más de 1 ya son muchas, salvo situaciones "especiales".
Responder Con Cita
  #4  
Antiguo 03-04-2006
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Pienso, aunque ya dec nos comentará más, que está haciendo algo así:

1. Una consulta que le devuelve decenas o cientos de registros
2. Procesar en un ciclo los registros y por cada uno hacer una nueva consulta, quizá para obtener detalles del registro.

de otra forma, como digo, ni siquiera imagino en qué situación se requieren cien consultas.

// Saludos
Responder Con Cita
  #5  
Antiguo 03-04-2006
Avatar de Emilio
*Emilio* Emilio is offline
Capo
 
Registrado: may 2003
Ubicación: Palma de Mallorca
Posts: 2.635
Poder: 10
Emilio Va por buen camino
No es muy frecuente realizar 100 consultas para un único documento, no obstante si es necesario no es una cifra que deba asustarnos si no son pesadas, a la que una de las consultas sea muy pesada puede dar más guerra que las otras 99
__________________
Saludos
Emilio
Responder Con Cita
  #6  
Antiguo 04-04-2006
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Gracias a todos por responder. El caso es que no he llegado aún a las 100 consultas por documento. Me quedo más acá... hoy mucho más acá, puesto que he estado "optimizando" el tema lo que he podido. Lo que ocurre es que mis conocimientos de MySQL, de SQL, de PHP, en fin, son bastante limitados y me voy encontrando con nuevos "problemas" casi a cada paso que doy.

Efectivamente, como Román se imagina, realizo unas consultas dentro de un "bucle", pero, tiene una explicación (claro que puede ser pésima). Yo tengo que mostrar una serie de registros de una base de datos. Para dichos registros, para la tabla que los contiene, he escrito una sencillísima clase en PHP, de tal manera que puedan crearse "objetos" por cada registro.

A ver si me explico un poco mejor. Digamos que el constructor de dicha clase recibe un número "ID". Si este número "ID" es válido, en un método de dicha clase se hace una consulta a la base de datos para obtener los datos del registro con ese "ID", para rellenar las propiedades del objeto en cuestión.

Hasta el momento no puedo "verlo" de otro modo. Pero, seguramente sea porque desconozco, como ya he dicho, SQL, MySQL, PHP, la programación "cliente/servidor", "por capas"... qué sé yo lo que desconozco... si lo conociera ya no lo desconocería. Esto es un galimatías del que no hay quien pueda salir airoso.

Por el momento el documento Web de marras ya no hace tantas consultas, si bien porque lo tengo "limitado". Digamos que muestro únicamente 4 registros por documento, porque es ahí donde veo dispararse el número de consultas. Ahora bien, me gustaría aclarar, y esto va un poco por lo que dice Emilio, que, no es que el documento "se eternize" en cargarse, o el ordenador eche chispas o algo así.

Todo va "bien", va "suave", no se demora en absoluto la carga del documento. Si bien me asustaba que pudieran hacerse "muchas" consultas, puesto que comprendo que una aplicación Web a la que pueden acceder varios usuarios conllevaría una multiplicación de las consultas en la misma medida en que se incrementasen los usuarios. De ahí mi miedo pánico.

Seguramente estoy haciendo una chapuza de aplicación, con código mal escrito, peor fundamentado, para nada pensado y hasta rumiado, o sea, que tampoco es algo que deba preocuparos. Terminaré diciendo que alucino con las cosas que hay por ahí funcionando. Verdaderamente el trabajo que deben llevar ciertas páginas Web es admirable.

Si bien no se me escapa aquello de Unamuno que decía que el trabajar mucho puede estar significando que se trabaja mal. Vale. Gracias otra vez por vuestras respuestas, seguiremos, de momento, tratando de avanzar algo con lo que nos traemos entre manos, si bien nos admira tanta... no encuentro la palabra adecuada.

¡Gracias otra vez pecadores de la pradera!
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #7  
Antiguo 04-04-2006
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Bueno. Después de hacer alguna que otra prueba, efectivamente, estaba dando una solución equivocada. Cuento un poco el caso, aunque no creo que le pueda servir de mucho a nadie. En definitiva se trataba de mostrar unos registros de cierta tabla de una base de datos. Entonces, como dije arriba, se me ocurrió escribir una clase para que "cargara" cada uno de los registros, de tal modo que pudiera acceder a las instancias de esta clase para obtener los datos necesarios.

Pero, ese planteamiento llevaba a lo siguiente:

1º Se hacía una consulta a la base de datos para averiguar con cuántos registros contaba un determinado usuario. La consulta SQL venía a quedar más o menos así, donde X es un número identificador de cualquier usuario:

Código SQL [-]
SELECT id FROM registros WHERE id_usuario = X

Eso era ya una primera consulta, ahora bien, ¿qué objetivo tiene esa consulta? Conseguir identificadores... conseguir los identificadores de los registros de un determinado usuario. ¿Y qué hacía luego con esos identificadores?

2º Instanciaba un objeto de la clase "Registro", pasando como parámetro en su constructor el identificador de marras, conseguido con la consulta de antes. ¡Pero esto generaba otra nueva consulta a la base de datos! ¿Y para qué? Pues para conseguir los datos del registro en cuestión, del que hasta ahora sabíamos su identificador, nada más.

3º Es en cierto método de la clase "Registro" en donde se hace la correspondiente consulta (y van dos):

Código SQL [-]
SELECT * FROM registros WHERE id = X

Lo que conocemos es la X, desde luego. Observad que se trabaja contra la misma tabla: ambas consultas tratan con la tabla "registros". ¿Qué estaba fallando aquí, para empezar? Pues que para cada identificador logrado con la primera consulta, se tiene que hacer una nueva consulta a la base de datos de modo que consigamos el resto de información necesaria...

Una locura. ¿Porqué? Pues porque podemos librarnos de la clase "Registros" y obtener los datos necesarios con la primera consulta y ninguna más. ¿Cómo? Pues, en lugar de pidiendo el identificador de cada registro, pidiendo todos sus campos, algo así:

Código SQL [-]
SELECT * FROM registros WHERE id_usuario = X

Y puede decirse que no pediremos todos los datos, puesto que utilizaremos el "LIMIT" de SQL, de tal forma que al final se haga una sola consulta que nos devuelva una decena de registros, por ejemplo. De momento, como he dicho, he mandado a freir espárragos a la clase "Registros" y estoy mostrando los datos, directamente, desde el resultado de la primera consulta. Una consulta contra tantas consultas como registros más una... vamos mejorando.

Gracias a todos, de nuevo, por responder. Seguramente sin sus comentarios no hubiera seguido adelante, o, cuando menos, me hubiera constado más darme cuenta de que estaba haciendo las cosas, ya no mal, pero peor.
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #8  
Antiguo 04-04-2006
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Bueno dec, contigo hay que leer entre líneas. Tú ya te deshiciste de la clase Registro pero nosotros nada más la vimos pasar rápidamente frente a nuestros ojos.

Te voy a decir lo que yo creo que intentaste y ya me dirás si era así o no.

Pero antes voy a fijar ideas, me cuesta trabajo hablar siempre en abstracto de ciertos registros, ciertas tablas, cierto sistema. Así que supongamos que tienes una tabla de personas:

personas = (id, nombre, telefono)

donde id es la llave primaria.

Tú quieres ver a cada persona con clase:

Código PHP:
class Persona
{
  var 
idnombretelefono;

y qué elegante poder dotar a esta clase de un método para cargar los datos de una persona desde la base de datos partiendo de su identificador:

Código PHP:
class Persona
{
  var 
idnombretelefono;

  function 
load(id)
  {
    
$statement "select * from personas where id =$id";
    
$results mysql_query($statement);
    
$result mysql_fetch_assoc($results);

    
$this->id id;
    
$this->nombre $result['nombre'];
    
$this->telefono $result['telefono'];
  }

Muy bonito, así haces:

Código PHP:
$persona = new Persona();
$persona->load(84); 
Y ¡listo! ya tienes a la persona con id = 84.

Pero entonces quieres una lista de personas y la clase sólo sabe cargar los datos de una sóla a la vez.

¿Va por ahí la cosa? Dime que me muero de curiosidad.

// Saludos
Responder Con Cita
  #9  
Antiguo 04-04-2006
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Román, no es que vaya por ahí la cosa, es que lo has descrito tal cual era.

Cita:
Empezado por Román
(...) y qué elegante poder dotar a esta clase de un método para cargar los datos (...)
... esto ya es cachondeo.
__________________
David Esperalta
www.decsoftutils.com

Última edición por dec fecha: 04-04-2006 a las 18:34:03.
Responder Con Cita
  #10  
Antiguo 04-04-2006
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Y ¿entonces por qué no seguir con esa idea?

Si observas el método load() verás que tiene dos partes: una que hace la consulta sql y otra que transfiere los datos de los resultados a la clase. Esta última parte la puedes separar en otro método:

Código PHP:
class Persona 

  var 
idnombretelefono

  function 
populate($result)
  {
    
$this->nombre $result['nombre']; 
    
$this->telefono $result['telefono']; 
  }

  function 
load(id
  { 
    
$statement "select * from personas where id =$id"
    
$results mysql_query($statement); 
    
$result mysql_fetch_assoc($results); 

    
$this->id $result['id'];
    
$this->populate($results);
  } 

Para listas de objetos puedes hacerte de otra clase:

Código PHP:
class ListaPersonas
{
  var 
$items;

  function 
ListaPersonas()
  {
    
$items = array();
  }

  function 
loadAll()
  {
    
$statement "select * from personas";
    
$results mysql_query($statement); 

    while (
$result mysql_fetch_assoc($results))
    {
      
$persona = new Persona();
      
$persona->id $result['id'];
      
$persona->populate($result);

      
$this->items[] = $persona;
    }
  }

Así, en $personas->items tendrás todas las personas con una sóla consulta sql. Al separar la consulta sql de la transferencia de datos, logras reutilizar esta última para llenar tu lista de persona obtenida de una sóla consulta.

Sin embargo esto en mi opinión aún no es óptimo. Normalmente requerirás recorrer este arreglo para procesarlo, por ejemplo para mostrarlo en la página:

Código PHP:
// Obtienes todas las personas
$personas = new ListaPersonas();
$personas->loadAll();

// Imprimes encabezado de la tabla
print "<table>";
print 
"<tr>";
print 
"<th>nombre</th>";
print 
"<th>telefono</th>";
print 
"</tr>";

foreach (
$personas->items as $persona)
{
  print 
"<tr>";
  print 
"<td>persona->nombre</td>";
  print 
"<td>persona->telefono</td>";
  print 
"</tr>";
}

print 
"</table>"
Pero entonces ya recorriste dos veces la lista de personas, una para formar el arreglo y otra para procesar éste. Además mantienes innecesariamente en memoria toda la lista de personas lo que puede no ser muy bueno para muchos registros.

Entonces, puedes optar por dejar que sea la misma clase ListaPersonas quien haga la iteración:

Código PHP:
class ListaPersonas
{
  var 
$results// resultados sql
  
var $persona// persona actual en la iteración 

  
function ListaPersonas()
  {
    
$this->persona = new Persona();
  }

  function 
loadAll()
  {
    
$statement "select * from personas";

    
// guardas los resultados para su posterior iteración
    
$this->results mysql_query($statement); 
  }

  
// Iterador
  // Devuelve la siguiente persona o false si no hay más personas
  
function next()
  {
    
$result mysql_fetch_assoc($this->results);
    if (
$result)
    {
      
$persona->id $result['id'];
      
$persona->populate($result);

      return 
$persona;
    }

    return 
false;
  }

Así, la construcción de la tabla te queda así:

Código PHP:
$personas = new ListaPersonas();
$personas->loadAll();

// Imprimes encabezado de la tabla
print "<table>";
print 
"<tr>";
print 
"<th>nombre</th>";
print 
"<th>telefono</th>";
print 
"</tr>";

while (
$persona $personas->next())
{
  print 
"<tr>";
  print 
"<td>persona->nombre</td>";
  print 
"<td>persona->telefono</td>";
  print 
"</tr>";
}

print 
"</table>"
El punto aquí, es que ahora sólo tienes un objeto Persona a la vez. Normalmente esto es suficiente: en un recorrido haces todo lo que haya que hacer con la persona en turno y te olvidas de la lista. Como te mencioné en algún otro hilo, al no estar trabajando con aplicaciones de escritorio, no tiene mucho objeto preservar la lista para otras cosas ya que al término del script ésta de cualquier manera dejará de existir.

Dime qué piensas y quizá podamos continuar las ideas.

// Saludos
Responder Con Cita
  #11  
Antiguo 04-04-2006
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Bueno, Román, pues muchas gracias de nuevo. Efectivamente, yo había pensado ya en algo así como lo que has propuesto tú, lo que ocurre es que lo había hecho muy por encima, y, desde luego, no hubiera terminado haciéndolo como tú, sino de otra forma... quizá parecida, pero,... me permito dudarlo.

El caso es que he implementado el asunto tal y como has propuesto. Seguramente ese "iterador" de la clase "ListaPersonas" no hubiera llegado a existir, de haberlo dejado de mi cuenta... como poco habría hecho lo que tú has comentado: dos iteraciones. Me juego el cuello.

Gracias otra vez Román, de veras.
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #12  
Antiguo 04-04-2006
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Ahora lo que falta es hacer las clases Persona y ListaPersonas reusables. Lo único realmente específo de éstas es el nombre de la tabla y el mapeo para llenar las propiedades. Y así como tienes el método loadAll(), clases descendientes puedes declarar sus propios métodos para incluir criterios de búsqueda específicos, por ejemplo

Código PHP:
$personas->loadByNombre('%perez%');
$facturas->loadByCliente($clienteId); 
Si te interesa este tema puedes encontrar información buscando cosas como Data Access Objects, Value Objects, Business Objects, etc. en PHP.

// Saludos
Responder Con Cita
  #13  
Antiguo 04-04-2006
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.044
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
todos los días se aprende algo, hoy dormiré bien
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
podrian explicarme que significa este error Nelly Varios 1 26-01-2006 17:46:18
Me podrian decir cual es el Error!! juliopag1 Firebird e Interbase 2 28-09-2005 13:57:07
mi podrian ayudar a instalar firebird 1.5 edy_aca Firebird e Interbase 6 25-09-2004 13:51:08
Me podrian explicar como se utlizan los indices Markoz Firebird e Interbase 2 23-07-2003 03:46:01
consultas SQL entre delphi y MySQL docarrillo SQL 1 03-07-2003 02:31:22


La franja horaria es GMT +2. Ahora son las 21:44:44.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi