Foro de elhacker.net

Programación => Bases de Datos => Mensaje iniciado por: soy_nicanor en 10 Abril 2015, 03:09 am



Título: Consulta de multiples tablas de mysql
Publicado por: soy_nicanor en 10 Abril 2015, 03:09 am
Tengo varias tablas.

Estoy sacando con JOIN Pero me busca muy lento los datos.

Código
  1. sSQL = "SELECT medicamento.id_med, medicamento.medicamento, medicamento.casilla, medicamento.stockTotal, "+
  2.                "lote.id_lote, lote.stock, proveedores.id_lote, proveedores.id_pres, proveedores.id_lin, "+
  3.                "presentacion.presentacion, linea.linea, "+
  4.                "contenedor.entero, contenedor.fraccion, contenedor.minimo, "+
  5.                "precioventa.vEntero, precioventa.vFraccion, precioventa.vMinimo "+                
  6.                "FROM medicamento "+
  7.                "INNER JOIN lote ON lote.id_med = medicamento.id_med "+
  8.                "INNER JOIN proveedores ON proveedores.id_lote = lote.id_lote "+
  9.  
  10.                "INNER JOIN contenedor ON contenedor.id_lote = lote.id_lote "+
  11.                "INNER JOIN precioventa ON precioventa.id_lote = lote.id_lote "+
  12.                "INNER JOIN presentacion ON presentacion.id_pres = proveedores.id_pres "+
  13.                "INNER JOIN linea ON linea.id_lin = proveedores.id_lin "+
  14.                "WHERE CONCAT(medicamento.medicamento) LIKE '%"+valor+"%' GROUP BY medicamento";
  15.  

Necesito otra forma de consultar para que sea rápido la consulta.


Título: Re: Consulta de multiples tablas de mysql
Publicado por: Usuario Invitado en 10 Abril 2015, 04:45 am
Hola. Éste tema debe ir en bases de datos. Cualquier cosa que tenga que ver con SQL o NoSQL, debe ir allí. Por favor, revisa bien el ámbito de tu problema para elegir la categoría correcta.

¿Cuántos registros tienes en la BBDD?


Título: Re: Consulta de multiples tablas de mysql
Publicado por: fran800m en 16 Abril 2015, 21:17 pm
Una select a 7 tablas te tiene que tardar, de todas formas yo trabajo con tablas de 66 millones de registros en MySql y estando indizado tarda relativamente poco.

Prueba a crear índices en los campos donde unes las tablas y para medicamento.medicamento

¿Por qué haces ese concat? ¿Y ese group by????


Título: Re: Consulta de multiples tablas de mysql
Publicado por: Hadess_inf en 24 Abril 2015, 18:39 pm
Usa explain analice para ver como trabaja tu consulta, después podrías crear indices donde corresponde.

Saludos.


Título: Re: Consulta de multiples tablas de mysql
Publicado por: ZeroVzla en 17 Mayo 2015, 06:28 am
Hola,

También puedes usar with que te permite tener especificar tablas temporales con ciertas condiciones de búsqueda antes de enlazar con las demás. Pasarías de enlazar 10 filas de tabla A con otras 10 filas de tabla B (suponiendo que ambas tablas tienen 10 filas)... a enlazar 5 filas de la tabla A que cumplen cierta condición con 3 filas de la tabla B que también cumplen otras condiciones.

Por ejemplo:

Código
  1. WITH Sales_CTE (SalesPersonID, TotalSales, SalesYear)
  2. AS
  3. -- Define the first CTE query.
  4. (
  5.    SELECT SalesPersonID, SUM(TotalDue) AS TotalSales, YEAR(OrderDate) AS SalesYear
  6.    FROM Sales.SalesOrderHeader
  7.    WHERE SalesPersonID IS NOT NULL
  8.       GROUP BY SalesPersonID, YEAR(OrderDate)
  9.  
  10. )
  11. ,   -- Use a comma to separate multiple CTE definitions.
  12.  
  13. -- Define the second CTE query, which returns sales quota data by year for each sales person.
  14. Sales_Quota_CTE (BusinessEntityID, SalesQuota, SalesQuotaYear)
  15. AS
  16. (
  17.       SELECT BusinessEntityID, SUM(SalesQuota)AS SalesQuota, YEAR(QuotaDate) AS SalesQuotaYear
  18.       FROM Sales.SalesPersonQuotaHistory
  19.       GROUP BY BusinessEntityID, YEAR(QuotaDate)
  20. )
  21.  
  22. -- Define the outer query by referencing columns from both CTEs.
  23. SELECT SalesPersonID
  24.  , SalesYear
  25.  , FORMAT(TotalSales,'C','en-us') AS TotalSales
  26.  , SalesQuotaYear
  27.  , FORMAT (SalesQuota,'C','en-us') AS SalesQuota
  28.  , FORMAT (TotalSales -SalesQuota, 'C','en-us') AS Amt_Above_or_Below_Quota
  29. FROM Sales_CTE
  30. JOIN Sales_Quota_CTE ON Sales_Quota_CTE.BusinessEntityID = Sales_CTE.SalesPersonID
  31.                    AND Sales_CTE.SalesYear = Sales_Quota_CTE.SalesQuotaYear
  32. ORDER BY SalesPersonID, SalesYear;
  33. GO
  34.  

Obtenido de https://msdn.microsoft.com/es-ve/library/ms175972.aspx (https://msdn.microsoft.com/es-ve/library/ms175972.aspx).

De igual manera y como lo indican en las respuestas anteriores los índices, usados correctamente, son de extrema importancia en las base de datos con grandes cantidades de registros. Busca cuáles son las condiciones de búsqueda que siempre usas y crea un índice de ellas.

Por otra parte veo que usas concat y no concatenas nada en realidad eso te resta velocidad ya que llevas a cabo la operación sobre cada registro sin necesidad y además de ello tienes el uso del LIKE que también trabaja bastante lento.

Te recomiendo algo, si en verdad tienes que concatenar, por ejemplo concat(medicamento.medicamento, medicamento.casilla) y ésa búsqueda es sumamente repetitiva o puesto de otra manera se lleva a cabo muchas, muchas veces... entonces puedes crear un índice de la misma, así el manejador no tiene que llevar a cabo la instrucción "concat(medicamento.medicamento, medicamento.casilla)" sobre todas las filas cada vez que alguien genere ésa consulta sino que se va al índice y ya.

Otra recomendación (se me ocurrió pero no se que tan buena es) es crear un select en el que encuentres primero el producto, en éste caso la medicina, y luego llevas a cabo varios subselects, se me ocurre que de ésta manera no enlazas tantas tablas y puede generarse más rápido la salida, algo como:

Código
  1. SELECT medicamento.id_med, medicamento.medicamento, medicamento.casilla, medicamento.stockTotal,
  2. (SELECT lote.id_lote FROM lote WHERE lote.id_med = medicamento.id_med),
  3. (SELECT lote.stock FROM lote WHERE lote.id_med = medicamento.id_med),
  4. (SELECT proveedores.id_lin FROM proveedores WHERE proveedores.id_lote = lote.id_lote)
  5. .
  6. .
  7. .
  8. .
  9. FROM medicamento
  10. WHERE CONCAT(medicamento.medicamento, medicamento.casilla) LIKE '%"+valor+"%' GROUP BY medicamento
  11.  

De ésta manera, creeeeeo, el manejador llevará a cabo la consulta principal (el select con la condición where) y luego llevará a cabo las subconsultas para buscar las demás columnas.

Espero te sirva.