Consulta de multiples tablas de mysql

Iniciado por soy_nicanor, 10 Abril 2015, 03:09 AM

0 Miembros y 1 Visitante están viendo este tema.

soy_nicanor

Tengo varias tablas.

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

Código (sql) [Seleccionar]

sSQL = "SELECT medicamento.id_med, medicamento.medicamento, medicamento.casilla, medicamento.stockTotal, "+
               "lote.id_lote, lote.stock, proveedores.id_lote, proveedores.id_pres, proveedores.id_lin, "+
               "presentacion.presentacion, linea.linea, "+
               "contenedor.entero, contenedor.fraccion, contenedor.minimo, "+
               "precioventa.vEntero, precioventa.vFraccion, precioventa.vMinimo "+                
               "FROM medicamento "+
               "INNER JOIN lote ON lote.id_med = medicamento.id_med "+
               "INNER JOIN proveedores ON proveedores.id_lote = lote.id_lote "+
               
               "INNER JOIN contenedor ON contenedor.id_lote = lote.id_lote "+
               "INNER JOIN precioventa ON precioventa.id_lote = lote.id_lote "+
               "INNER JOIN presentacion ON presentacion.id_pres = proveedores.id_pres "+
               "INNER JOIN linea ON linea.id_lin = proveedores.id_lin "+
               "WHERE CONCAT(medicamento.medicamento) LIKE '%"+valor+"%' GROUP BY medicamento";


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

Usuario Invitado

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?
"La vida es muy peligrosa. No por las personas que hacen el mal, si no por las que se sientan a ver lo que pasa." Albert Einstein

fran800m

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????

Hadess_inf

Usa explain analice para ver como trabaja tu consulta, después podrías crear indices donde corresponde.

Saludos.

ZeroVzla

#4
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 (sql) [Seleccionar]

WITH Sales_CTE (SalesPersonID, TotalSales, SalesYear)
AS
-- Define the first CTE query.
(
   SELECT SalesPersonID, SUM(TotalDue) AS TotalSales, YEAR(OrderDate) AS SalesYear
   FROM Sales.SalesOrderHeader
   WHERE SalesPersonID IS NOT NULL
      GROUP BY SalesPersonID, YEAR(OrderDate)

)
,   -- Use a comma to separate multiple CTE definitions.

-- Define the second CTE query, which returns sales quota data by year for each sales person.
Sales_Quota_CTE (BusinessEntityID, SalesQuota, SalesQuotaYear)
AS
(
      SELECT BusinessEntityID, SUM(SalesQuota)AS SalesQuota, YEAR(QuotaDate) AS SalesQuotaYear
      FROM Sales.SalesPersonQuotaHistory
      GROUP BY BusinessEntityID, YEAR(QuotaDate)
)

-- Define the outer query by referencing columns from both CTEs.
SELECT SalesPersonID
 , SalesYear
 , FORMAT(TotalSales,'C','en-us') AS TotalSales
 , SalesQuotaYear
 , FORMAT (SalesQuota,'C','en-us') AS SalesQuota
 , FORMAT (TotalSales -SalesQuota, 'C','en-us') AS Amt_Above_or_Below_Quota
FROM Sales_CTE
JOIN Sales_Quota_CTE ON Sales_Quota_CTE.BusinessEntityID = Sales_CTE.SalesPersonID
                   AND Sales_CTE.SalesYear = Sales_Quota_CTE.SalesQuotaYear
ORDER BY SalesPersonID, SalesYear;
GO


Obtenido de 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 (sql) [Seleccionar]

SELECT medicamento.id_med, medicamento.medicamento, medicamento.casilla, medicamento.stockTotal,
(select lote.id_lote from lote where lote.id_med = medicamento.id_med),
(select lote.stock from lote where lote.id_med = medicamento.id_med),
(select proveedores.id_lin from proveedores where proveedores.id_lote = lote.id_lote)
.
.
.
.
FROM medicamento
WHERE CONCAT(medicamento.medicamento, medicamento.casilla) LIKE '%"+valor+"%' GROUP BY medicamento


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.