我正在寻找优化以下用于计算多个商店的库存成本的Mysql查询,我通过PHP循环为每个不同的商店运行以下查询并输出结果:
查询:
SELECT
SUM((((
(SELECT COALESCE(SUM(facturas_fabrica.cantidad), 0)
FROM facturas_fabrica
INNER JOIN entradas_pedidos_productos ON
entradas_pedidos_productos.clave = facturas_fabrica.entradas_pedidos_productos_clave
INNER JOIN entradas_pedidos ON entradas_pedidos.clave = entradas_pedidos_productos.entradas_pedidos_clave
WHERE entradas_pedidos_productos.producto_id = productos.id
AND facturas_fabrica.procesado_local = 1 AND entradas_pedidos.sucursal_id = '.$row['id'].' # store id
AND DATE(facturas_fabrica.fecha_procesada) <= DATE(NOW()))
-
(SELECT COALESCE(SUM(cantidad), 0)
FROM facturas_contenido
WHERE producto_id = productos.id AND facturas_contenido.sucursal_id = '.$row['id'].'
AND DATE(facturas_contenido.fecha_creacion) <= DATE(NOW()))
+
(SELECT COALESCE(SUM(cantidad), 0)
FROM notas_de_credito_contenido
WHERE producto_id = productos.id AND notas_de_credito_contenido.sucursal_id = '.$row['id'].'
AND DATE(notas_de_credito_contenido.fecha_creacion) <= DATE(NOW()))
-
(SELECT COALESCE(SUM(salidas_devoluciones.cantidad), 0)
FROM salidas_devoluciones
WHERE producto_id = productos.id AND (estado = 2 OR estado = 3) AND modulo != 2 AND salidas_devoluciones.sucursal_id = '.$row['id'].' # store id
AND DATE(salidas_devoluciones.fecha_envio) <= DATE(NOW()))
) * productos.costo) / 100) ) AS "'.$row['clave'].'" # store name
FROM productos WHERE 1
(我只保留与查询相关的字段)
表1:
CREATE TABLE `productos` (
`id` int(10) unsigned NOT NULL,
`costo` int(10) NOT NULL,
PRIMARY KEY (`id`),
KEY `costo` (`costo`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
表2:
CREATE TABLE `facturas_fabrica` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`clave` bigint(20) unsigned NOT NULL,
`entradas_pedidos_productos_clave` bigint(20) unsigned NOT NULL,
`cantidad` tinyint(3) unsigned NOT NULL,
`procesado_local` tinyint(1) NOT NULL DEFAULT '0',
`fecha_procesada` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `clave_UNIQUE` (`clave`),
KEY `fk_entradas_pedidos_productos_clave_idx` (`entradas_pedidos_productos_clave`),
KEY `facturas_fabrica_procesado_local` (`procesado_local`),
KEY `facturas_fabrica_cantidad` (`cantidad`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Constraints for table `facturas_fabrica`
--
ALTER TABLE `facturas_fabrica`
ADD CONSTRAINT `fk_entradas_pedidos_productos_clave` FOREIGN KEY (`entradas_pedidos_productos_clave`) REFERENCES `entradas_pedidos_productos` (`clave`) ON DELETE NO ACTION ON UPDATE NO ACTION;
表3:
CREATE TABLE `entradas_pedidos_productos` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`clave` bigint(20) unsigned NOT NULL,
`entradas_pedidos_clave` bigint(20) unsigned NOT NULL,
`producto_id` int(10) unsigned NOT NULL,
`cantidad` tinyint(3) unsigned NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `clave_UNIQUE` (`clave`),
KEY `fk_pedidos_producto_id_idx` (`producto_id`),
KEY `fk_pedidos_productos_pedido_clave_idx` (`entradas_pedidos_clave`),
KEY `entradas_productos_cantidad` (`cantidad`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Constraints for table `entradas_pedidos_productos`
--
ALTER TABLE `entradas_pedidos_productos`
ADD CONSTRAINT `fk_pedidos_productos_pedido_clave` FOREIGN KEY (`entradas_pedidos_clave`) REFERENCES `entradas_pedidos` (`clave`) ON DELETE NO ACTION ON UPDATE NO ACTION,
ADD CONSTRAINT `fk_pedidos_productos_producto_id` FOREIGN KEY (`producto_id`) REFERENCES `productos` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION;
表4:
CREATE TABLE `entradas_pedidos` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`clave` bigint(20) unsigned NOT NULL,
`sucursal_id` tinyint(3) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `clave_UNIQUE` (`clave`),
KEY `clave` (`clave`),
KEY `entradas_sucursal` (`sucursal_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Constraints for table `entradas_pedidos`
--
ALTER TABLE `entradas_pedidos`
ADD CONSTRAINT `fk_entradas_pedidos_sucursal_is` FOREIGN KEY (`sucursal_id`) REFERENCES `sucursales` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION;
表5:
CREATE TABLE `facturas_contenido` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`clave` bigint(20) unsigned NOT NULL,
`sucursal_id` tinyint(3) NOT NULL,
`producto_id` int(10) unsigned NOT NULL,
`cantidad` tinyint(3) unsigned NOT NULL,
`fecha_creacion` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `clave_factura_contenido` (`clave`),
KEY `fk_orden_contenido_producto_id_idx` (`producto_id`),
KEY `facturas_contenido_cantidad` (`cantidad`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Constraints for table `facturas_contenido`
--
ALTER TABLE `facturas_contenido`
ADD CONSTRAINT `fk_facturas_clave` FOREIGN KEY (`factura_clave`) REFERENCES `facturas` (`clave`) ON DELETE NO ACTION ON UPDATE NO ACTION,
ADD CONSTRAINT `fk_facturas_contenido_producto_id` FOREIGN KEY (`producto_id`) REFERENCES `productos` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION;
表6:
CREATE TABLE `notas_de_credito_contenido` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`clave` bigint(20) unsigned NOT NULL,
`sucursal_id` tinyint(3) NOT NULL,
`producto_id` int(10) unsigned NOT NULL,
`cantidad` tinyint(3) unsigned NOT NULL,
`fecha_creacion` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `clave_nota_de_credito_contenido` (`clave`),
KEY `fk_nc_clave_idx` (`nc_clave`),
KEY `fk_ordenes_contenido_clave_idx` (`nc_facturas_contenido_clave`),
KEY `notas_de_credito_cantidad` (`cantidad`),
KEY `notas_de_credito_producto_id` (`producto_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Constraints for dumped tables
--
--
-- Constraints for table `notas_de_credito_contenido`
--
ALTER TABLE `notas_de_credito_contenido`
ADD CONSTRAINT `fk_facturas_contenido_clave` FOREIGN KEY (`nc_facturas_contenido_clave`) REFERENCES `facturas_contenido` (`clave`) ON DELETE NO ACTION ON UPDATE NO ACTION,
ADD CONSTRAINT `fk_nc_clave` FOREIGN KEY (`nc_clave`) REFERENCES `notas_de_credito` (`clave`) ON DELETE NO ACTION ON UPDATE NO ACTION;
表7:
CREATE TABLE `salidas_devoluciones` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`clave` bigint(20) unsigned NOT NULL,
`producto_id` int(10) unsigned NOT NULL,
`cantidad` tinyint(3) unsigned NOT NULL,
`sucursal_id` tinyint(3) NOT NULL,
`fecha_envio` timestamp NULL DEFAULT NULL,
`estado` tinyint(3) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `clave_UNIQUE` (`clave`),
KEY `salidas_devoluciones_cantidad` (`cantidad`),
KEY `fk_salidas_producto_id_idx` (`producto_id`),
KEY `devoluciones_estado` (`estado`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Constraints for table `salidas_devoluciones`
--
ALTER TABLE `salidas_devoluciones`
ADD CONSTRAINT `fk_salidas_producto_id` FOREIGN KEY (`producto_id`) REFERENCES `productos` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION;
问题是由于每个商店中的大量商店和移动,查询变得越来越重,并且因为库存是从每个商店的历史开始计算的,所以只会随着时间的推移而变慢。
如何优化此方案?