Debt Consolidation - Computers 2007 - Debt Consolidation - Bob's Free Stuff Forum - Free Advertising

PDA

View Full Version : HELP to optimize a query


amota
Jun 1st 2006, 10:00 am
Hi,
I have a query to consult several tables. It works but it's too slow!
I need to do it faster! Please, someone helps me.

TABLE DEFINITIONS:

CREATE TABLE `importaciones` (
`idcliente` varchar(13) NOT NULL default '',
`pedido` varchar(20) default NULL,
`producto` varchar(255) default NULL,
`do` varchar(12) NOT NULL default '',
`fec_actual` date default NULL,
`ciudad` varchar(20) default NULL,
`razon` varchar(255) default NULL,
`tabla` char(1) default 'I',
PRIMARY KEY (`do`),
KEY `do` (`do`),
KEY `pedido` (`pedido`),
KEY `horas` (`horas`),
KEY `ciudad` (`ciudad`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE `exportaciones` (
`idcliente` varchar(13) default NULL,
`do` varchar(15) NOT NULL default '',
`pedido` varchar(15) default NULL,
`ciudad` varchar(50) default NULL,
`producto` text,
`razon` varchar(255) default NULL,
`tabla` char(1) default 'E',
PRIMARY KEY (`do`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE `plantilla` (
`id` int(7) NOT NULL auto_increment,
`idproceso` tinyint(4) default NULL,
`idactividad` varchar(5) default NULL,
`desc_actividad` varchar(255) default NULL,
PRIMARY KEY (`id`),
KEY `idproceso` (`idproceso`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE `procesos` (
`idproceso` tinyint(4) NOT NULL default '0',
`nombre` varchar(30) default NULL,
`nombrecorto` varchar(10) default NULL,
PRIMARY KEY (`idproceso`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE `estadohechos` (
`regn` mediumint(8) unsigned NOT NULL auto_increment,
`numdo` varchar(8) NOT NULL default '',
`etapa` varchar(4) NOT NULL default '',
`fecha` date NOT NULL default '0000-00-00',
`hora` time NOT NULL default '00:00:00',
`tipo` tinyint(2) NOT NULL default '0' COMMENT 'Si es interrupción o normal',
`regusu` mediumint(6) unsigned NOT NULL default '0',
`observaciones` text NOT NULL,
`flag` char(1) NOT NULL default '',
`sede` tinyint(3) default NULL COMMENT '1=Ctg,2=Barr,3=Bog,4=Bvt',
`grabado` timestamp NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
PRIMARY KEY (`regn`),
KEY `PorInterrup` (`numdo`,`etapa`,`tipo`),
KEY `PorNumDO` (`numdo`,`etapa`,`fecha`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC;

CREATE TABLE `ordenes` (
`regn` mediumint(8) NOT NULL auto_increment,
`proceso` tinyint(4) NOT NULL default '0',
`numdo` varchar(8) NOT NULL default '',
`nitcliente` varchar(11) NOT NULL default '',
`terminado` tinyint(1) NOT NULL default '0',
PRIMARY KEY (`regn`),
UNIQUE KEY `PorNumDO` (`proceso`,`numdo`),
KEY `PorNitCliente` (`proceso`,`nitcliente`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC;

CREATE TABLE `etapas` (
`regn` smallint(5) unsigned NOT NULL auto_increment,
`proceso` tinyint(4) NOT NULL default '0',
`tipo` tinyint(4) NOT NULL default '0',
`codigo` char(4) NOT NULL default '',
`descripcion` char(30) NOT NULL default '',
PRIMARY KEY (`regn`),
KEY `PorEtapa` (`proceso`,`tipo`,`codigo`),
KEY `descripcion` (`descripcion`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=FIXED;


THE QUERY I NEED TO DO FASTER:

SELECT * FROM
(SELECT distinct `procesos`.`nombrecorto`, `importaciones`.`idcliente`, `importaciones`.`pedido`, `importaciones`.`razon`, `importaciones`.`do`, `importaciones`.`fec_actual`, `importaciones`.`producto`, `importaciones`.`ciudad`, `importaciones`.`tabla`,
(select et.descripcion from etapas et, estadohechos es
where es.etapa = et.codigo and `ordenes`.numdo=es.numdo
and et.descripcion <> 'ANULADO'
order by fecha,hora desc limit 1) AS estado,
(select et.descripcion from etapas et, estadohechos es
where es.etapa = et.codigo and `ordenes`.numdo=es.numdo
and et.descripcion <> 'ANULADO'
and et.codigo in
(select plantilla.idactividad from plantilla
where asercol.idproceso = ordenes.proceso)
order by fecha,hora desc limit 1) AS estado_as,
`ordenes`.`proceso`,
ordenes.terminado
FROM `importaciones`, ordenes, procesos, estadohechos
where (`importaciones`.`do` = `ordenes`.`numdo` and
`ordenes`.`proceso` = `procesos`.`idproceso` and
`importaciones`.`do` = estadohechos.`numdo` )
UNION
SELECT distinct `procesos`.`nombrecorto`, `exportaciones`.`idcliente`, `exportaciones`.`pedido`, `exportaciones`.`razon`, `exportaciones`.`do`, `asercol`.`exportaciones`.`fec_actual`, `exportaciones`.`producto`, `exportaciones`.`ciudad`, `exportaciones`.`tabla`,
(select et.descripcion from etapas et, estadohechos es
where es.etapa = et.codigo and `ordenes`.numdo=es.numdo
and et.descripcion <> 'ANULADO'
order by fecha,hora desc limit 1) AS etapa,
(select et.descripcion from etapas et, estadohechos es
where es.etapa = et.codigo and `ordenes`.numdo=es.numdo
and et.descripcion <> 'ANULADO'
and et.codigo in
(select plantilla.idactividad from plantilla
where plantilla.idproceso = ordenes.proceso)
order by fecha,hora desc limit 1) AS etapa_as,
`ordenes`.`proceso`,
ordenes.terminado as finalizado
FROM `exportaciones`, ordenes, procesos, estadohechos
where
`exportaciones`.`do` = `ordenes`.`numdo` and
`ordenes`.`proceso` = `procesos`.`idproceso` and
`exportaciones`.`do` = estadohechos.`numdo`
) AS TABLA[/COLOR]


In words, what I need is:
- all of the records from importaciones
- all of the records from exportaciones
Additional information found in:
- ordenes: 'proceso' - the short name which is in 'procesos'
'terminado'
- estadohechos-etapas: description of last 'etapa' done to 'do' (pk)

The thing is, my php application gets a timeout, so I can't execute this query.
Any help will be really appreciated!!!

Attached is the EXPLAIN Query result.

Dan Grossman
Jun 2nd 2006, 9:01 pm
Wow. A bit too much like work.. to optimize it for free =p

sadcox66
Jun 3rd 2006, 11:19 am
In words, what I need is:
- all of the records from importaciones
- all of the records from exportaciones


*Try not to get all the records. Only select those records you need for the task.
* Your WHERE condition should have the condition which gives the "tightest filter"
and you should have that column as an index.

kLdd15
Jun 6th 2006, 8:14 pm
Yeah, one of the most important things is the indexes for large tables.

sacx13
Jun 7th 2006, 1:07 am
And if you expect just one result from your subquerys then use limit 1.

Regards