Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

Como optimizar una consulta Mysql con select anidados... si es posible

Estas en el tema de Como optimizar una consulta Mysql con select anidados... si es posible en el foro de Mysql en Foros del Web. Ante todo muchas gracias por vuestra ayuda, os comento. Tengo una tabla clásica de categorias de artículos la cual tiene dos niveles, (nivel 0 y ...
  #1 (permalink)  
Antiguo 02/02/2011, 08:45
 
Fecha de Ingreso: enero-2005
Ubicación: Málaga
Mensajes: 30
Antigüedad: 19 años, 3 meses
Puntos: 1
Como optimizar una consulta Mysql con select anidados... si es posible

Ante todo muchas gracias por vuestra ayuda, os comento.

Tengo una tabla clásica de categorias de artículos la cual tiene dos niveles, (nivel 0 y nivel 1) y un campo padre que indica para el nivel 1 de que categoria cuelga.

Mi problema es que necesito cruzar la tabla de categorias con la tabla de articulos para saber cuantos articulos hay en cada categoria.... y claro, para mostrar el index (que es la muestra esta información hay que tirar mucho de la bbdd) y se resiente ...

Tengo una tabla intermedia "artículos_en_categorias" donde se almacena la relación

Esta es la consulta en concreto que hago ... y hago una por cada categoría que existe en el portal ya que necesito conoces ademas el numero de articulos de las categorias que cuelgan de cada una que se encuentra en el nivel 0 y claro... y hay mas de 200 ..

SELECT count(articulos_en_categorias.id_articulo) as total FROM articulos, articulos_en_categorias WHERE articulos_en_categorias.id_articulo = articulos.id_articulo AND articulos.expirado = '0' AND articulos.activo = '1' AND articulos.eliminado = '0' AND articulos.id_estado_articulo > 2 AND articulos.id_estado_articulo < 5 AND articulos_en_categorias.id_categoria = '22'

Por favor, se os ocurre como puedo obtener esta informacion de forma mas eficiente?? ...

¿Podría obtener el mismo resultado (articulos que hay en categorias) con sólo un select usando select anidados??? ... podría alguien indicarme como hacerlo?

Ahora estoy haciendo una consulta para las categorias en nivel 0, y con el resultado un bucle for en PHP donde luego para cada una de ellas obtengo ademas el numero de artículos que se encuentran en las categorias de nivel 1 que cuelgan de cada una de nivel 0 ...

Os pongo las tablas en concreto:

Código:
CREATE TABLE IF NOT EXISTS `articulos_en_categorias` ( 
`id_articulo` int(11) default NULL, 
`id_categoria` int(11) default NULL, 
`url` varchar(255) default NULL, 
KEY `fk_relationship_1` (`id_articulo`), 
KEY `fk_relationship_20` (`id_categoria`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 


CREATE TABLE IF NOT EXISTS `categorias` ( 
`id_categoria` int(11) NOT NULL auto_increment, 
`id_idioma` int(11) default NULL, 
`id_pais` int(11) default NULL, 
`id_categoria_encriptado` varchar(255) default NULL, 
`nombre` varchar(64) default NULL, 
`nombre_txt` varchar(64) default NULL, 
`tags` text, 
`relacion` varchar(64) default NULL, 
`nivel` int(11) default NULL, 
`padre` int(11) default NULL, 
`orden` int(11) default NULL, 
`activo` int(11) default NULL, 
PRIMARY KEY (`id_categoria`), 
KEY `fk_relationship_2` (`id_idioma`), 
KEY `fk_relationship_27` (`id_pais`), 
KEY `nivel` (`nivel`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=267 ; 


CREATE TABLE IF NOT EXISTS `articulos` ( 
`id_articulo` int(11) NOT NULL auto_increment, 
`id_cc` int(11) default NULL, 
`id_municipio` int(11) default NULL, 
`id_pago` int(11) default NULL, 
`id_provincia` int(11) default NULL, 
`id_usuario` int(11) default NULL, 
`id_solicitud_cambio` int(11) default NULL, 
`id_estado_articulo` int(11) default NULL, 
`id_articulo_encriptado` varchar(255) default NULL, 
`seudonimo` varchar(64) default NULL, 
`titulo` varchar(45) default NULL, 
`subtitulo` varchar(45) default NULL, 
`url` varchar(255) default NULL, 
`contenido` text, 
`numero_de_imagenes` int(11) default NULL, 
`imagen1` varchar(255) default NULL, 
`duracion_anuncio` int(11) default NULL, 
`precio_estimado` float(10,2) default NULL, 
`articulo_nuevo` int(11) default NULL, 
`fecha_creacion` datetime default NULL, 
`fecha_ultima_actualizacion` date default NULL, 
`relevancia` int(11) default NULL, 
`fecha_publicacion` datetime default NULL, 
`fecha_fin` datetime default NULL, 
`articulo_nuevo_usado` int(11) default NULL, 
`bloqueado_x_cambio` int(11) default NULL, 
`ofrecido` int(11) default NULL, 
`codigo_promocional` varchar(32) default NULL, 
`codigo_articulo` varchar(16) default NULL, 
`activo` int(11) default NULL, 
`eliminado` int(11) default NULL, 
`expirado` int(11) default NULL, 
`destacado` int(11) default NULL, 
PRIMARY KEY (`id_articulo`), 
KEY `fk_relationship_21` (`id_pago`), 
KEY `fk_relationship_23` (`id_usuario`), 
KEY `fk_relationship_24` (`id_provincia`), 
KEY `fk_relationship_25` (`id_solicitud_cambio`), 
KEY `fk_relationship_34` (`id_cc`), 
KEY `fk_relationship_35` (`id_municipio`), 
KEY `fk_relationship_5` (`id_estado_articulo`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=154 ;


Mi version de MySQL es 5.0.51a-24+lenny2-log


Muchas gracias por vuestra ayuda y un saludo
  #2 (permalink)  
Antiguo 02/02/2011, 10:08
Avatar de Heimish2000  
Fecha de Ingreso: enero-2011
Ubicación: Madrid
Mensajes: 844
Antigüedad: 13 años, 2 meses
Puntos: 89
Respuesta: Como optimizar una consulta Mysql con select anidados... si es posible

Yo te daré dos consejos, espero que te sirvan:
  1. Utiliza un INNER JOIN en vez de unir las tablas directamente poniendo la tabla más pequeña en primer lugar.
  2. En el WHERE escribe las claúsulas más restrictivas en primer lugar.

Etiquetas: anidados, posible, select
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 16:30.