Perl en Español

  1. Home
  2. Tutoriales
  3. Foro
  4. Artículos
  5. Donativos
  6. Publicidad
 
Índice general » Mundo Perl » Básico » Comparar tablas iguales Responder al tema
Nuevo tema


Página 1 de 1  [ 3 mensajes ] 
 
Nota Mié Jul 01, 2009 6:28 am

Perlero Nuevo
Registrado: Mié Jul 01, 2009 6:11 am
Mensajes: 2
Comparar tablas iguales
Hola todos:

En primer lugar me gustaría agradeceros la ayuda que prestáis en este foro, porque aunque es la primera vez que posteo vengo leyéndoos desde hace tiempo.

Os cuento mi problema:

Estoy escribiendo un script (en realidad ya está escrito) para detectar similaridades entre registros, para ello tengo que comparar la tabla dónde están estos registros consigo misma. En un principio probé a crear un producto cartesiano en la consulta SQL y funcionaba bien, pero cuando la tabla es muy grande produce millones de registros que no puedo procesar por cuestiones de memoria.

Lo siguiente que intenté es hacer dos consultas separadas, de forma que el script compara cada registro de una consulta con todos los registros de la otra. Funciona a las mil maravillas, pero el problema es que es muy lento (se demora alrededor de 8 horas con 5000 registros).

Os pongo el código:
Sintáxis: [ Descargar ] [ Ocultar ]
Usando Coloreado de perl
#!/usr/bin/perl
#Modulos utilizados:
use DBI;
use CONECTAR_ISI;
use TRIGRAM;

#Conectamos a la BBDD:
$dbh = Conectar->connect();

#Ejecutamos la primera consulta para extraer los campos a comparar

my $sth =
  $dbh->prepare(
"SELECT id, autor, direccion, categoria, coautores, revistas,
vid, vautor, vdireccion, vcategoria, vcoautores, vrevistas
FROM autoridades2
WHERE `vautor` NOT LIKE '%duplicado%'
ORDER BY autor ASC
"

  );
$sth->execute();
        my $sth2 =
          $dbh->prepare(
"SELECT id, autor, direccion, categoria, coautores, revistas,
vid, vautor, vdireccion, vcategoria, vcoautores, vrevistas
FROM autoridades2
WHERE `vautor` NOT LIKE '%duplicado%'
ORDER BY autor ASC
"

          );

#Convierte la consulta en un array
while (@lineas = $sth->fetchrow_array ) {

#Por cada línea encontrada en la consulta ejecutamos la siguiente para hacer
#las comparaciones

$sth2->execute();
while ( @lineas2 = $sth2->fetchrow_array() ) {

#CODIGO PARA HACER COMPARACIONES
}
}
$sth->finish();
$sth2->finish();
$dbh->disconnect();


He probado a poner el "$dbh2->execute()" antes del primer "while" pero entonces me devuelve un error "DBD::mysql::st fetchrow_array failed: fetch() without execute()"

A ver si podéis echarme una mano, porque yo ya no sé qué hacer para optimizarlo...


Nota Jue Jul 02, 2009 6:45 am
Avatar de Usuario
Administrador
Registrado: Dom Jul 24, 2005 6:12 pm
Ubicación: Valladolid, España
Mensajes: 6870
Bienvenido a los foros de Perl en Español, eleazaar.

Pues yo creo que el problema está justo en la comparación.

Si es simple, se podría resolver con los diccionarios (hash).

Lo primero que veo es que podrías ahorrartge las consultas mas interfnas, cacheandolas en memoria.

_________________
JF^D Perl programming


Nota Jue Jul 02, 2009 8:19 am

Perlero Nuevo
Registrado: Mié Jul 01, 2009 6:11 am
Mensajes: 2
Hola explorer, muchas gracias por tu ayuda. Efectivamente el problema está en las comparaciones, que son algo complicadas, porque tengo que obtener diferentes cálculos de similaridad para los diferentes campos de cada consulta.

Probé lo que sugieres de cachear las consultas en memoria usando fetchall_array() pero pierdo una funcionalidad importante y es que si el script considera que una línea posee un equivalente más completo no quiero que vuelva a compararla, así que le inserto un "duplicado" en uno de los campos y así no vuelve a traer esa fila al hacer la siguiente consulta, pero si las cacheo en memoria pierdo esa funcionalidad, que realmente me interesa más que lo que pueda tardar en ejecutarse el script.

Aunque no perdí la esperanza de optimizar el código y esta tarde lo conseguí pasando una condición en un "if" antes de empezar a calcular las similaridades, así que sin que se alteren los resultados he conseguido pasar de casi 9 horas de ejecución a una hora y media aproximadamente. Seguramente pueda hacerse mejor, más rápido y más limpio, pero por ahora funciona ¡¡¡y en la cuarta parte de tiempo!!!

Muchas gracias de todas formas, probablemente siga preguntando cosillas, porque apenas empiezo con esto de Perl.

¡Saludos!


Responder al tema  [ 3 mensajes ] 

Reglas del Foro
No puede abrir nuevos temas en este Foro
No puede responder a temas en este Foro
No puede editar sus mensajes en este Foro
No puede borrar sus mensajes en este Foro
No puede enviar adjuntos en este Foro

Publicidad

Socializa

Síguenos por Twitter

Suscríbete GRATUITAMENTE al Boletín de Perl en Español

Saltar a:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Traducción al español por Huan Manwë
phpBB SEO