Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Bases de datos > Firebird e Interbase
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 13-11-2023
Avatar de duilioisola
[duilioisola] duilioisola is offline
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.734
Poder: 20
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
PD.

Después de ejecutar el script, todo iba muy lento.
He tenido que recaclular los índices para que todo vaya bien.

IbExpert tiene la opción de ir a DataBase-> Recompute celectivity of all Indeces

Básicamente recorre los índices de la base de datos y ejecuta SET STATISTICS INDEX [IndexName]:
Código SQL [-]
SET STATISTICS INDEX DISMES;

SET STATISTICS INDEX MUNMES;

SET STATISTICS INDEX PK_MESAS;

SET STATISTICS INDEX PK_NUMELECTOS;

SET STATISTICS INDEX PK_PARTIDOS;

SET STATISTICS INDEX PK_POBLACION;

SET STATISTICS INDEX PK_RESULTADOS;
Responder Con Cita
  #2  
Antiguo 14-11-2023
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
Cita:
Empezado por duilioisola Ver Mensaje
PD.

Después de ejecutar el script, todo iba muy lento.
He tenido que recaclular los índices para que todo vaya bien.
Muchísimas gracias pro tu ayuda. Has hecho un pleno. Sólo he tenido que cambiar una cosa para que me saque todos los municipios, pero el query es perfecto.

Por otra parte, sobre la velocidad de ejecución he de decirte que para sacar todos los municipios a mi en SQL Manager me ha tardado 62 milisegundos. Únicamente las lecturas de la tabla mesas se hacen sin usar índices; tengo que ver por qué.
Responder Con Cita
  #3  
Antiguo 14-11-2023
Avatar de duilioisola
[duilioisola] duilioisola is offline
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.734
Poder: 20
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
A mi también me va muy rápida la consulta, pero al principio los índices estaban desbalanceados (supongo que por el insert masivo del script) y todos tenínan un valor de 1 (o 0, no recuerdo bien).
Las estadísticas de los índices es una parte importante de lo que mira el planificador de SQL al hacer los JOINS.


Esto te devuelve las estadísticas de los índices y deberían tener valores lo más bajo posibles sin ser 0.
Código SQL [-]
select rdb$relation_name, rdb$index_name, rdb$statistics
from rdb$indices
where
/* Evito indices de sistema */
rdb$system_flag = 0
order by rdb$relation_name, rdb$index_name

Esto es lo que me devuelve ahora, después de ejeructar el "SET STATISTICS [indice]".
Código:
RDB$RELATION_NAME   RDB$INDEX_NAME   RDB$STATISTICS
-----------------   --------------   --------------
MESAS               DISMES           0,001355013577
MESAS               MUNMES           0,009803921916
MESAS               PK_MESAS         0,001355013577
NUMELECTOS          PK_NUMELECTOS    0,001915708766
PARTIDOS            PK_PARTIDOS      0,018518518656
POBLACION           PK_POBLACION     0,000017048846
RESULTADOS          PK_RESULTADOS    0,000008809486
Responder Con Cita
  #4  
Antiguo 14-11-2023
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
Es decir que cuanto más bajo sea ese valor mejor está el índice. No lo sabía; todos los días se aprende algo.

Otra cosa: Si ejecuto el query para que me saque todos los municipios, cambiando la línea
Código SQL [-]
m.municipio = 175
por
Código SQL [-]
m.municipio = po.codigo
me ocurre una cosa que, al menos a mi, me llama la atención.
Table Operations:
+-----------------
Table Name | Index | Non-Index
| reads | reads
+--------------------------+-----------+
MESAS| 0 | 1.476 |
NUMELECTOS| 4.534 | 0 |
PARTIDOS| 5.786 | 0 |
POBLACION| 1.476 | 0 |
PROVINCIA| 5.786 | 0 |
RESULTADOS| 5.786 | 0 |

La tabla mesas tiene tres índices: la clave primaria (CodPrv + Codigo) y dos índices: uno por CodPrv y Municipio y el otro por todos los datos identificativos de la mesa. Y dado que las búsquedas en las que interviene la tabla Mesas se hacen por alguno de los campos indexados, prinicipalmente municipio y código de mesa), ¿por qué no se usan los índices para esas búsquedas?
Responder Con Cita
  #5  
Antiguo 14-11-2023
Avatar de duilioisola
[duilioisola] duilioisola is offline
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.734
Poder: 20
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
El número de los índices indica cuan específico es. Entiéndase cuan único es cada registro.
Si tienes una tabla ARTICULOS (EMPRESA, ARTICULO) y tienes los valores
Código:
1, ART1
1, ART2
1, ART3
1, ART4
un índice por EMPRESA tendrá estadística = 1, indicando que se repite para todos los registros
un índice por ARTICULO tendra estadística = 0,25, indicando que "se repite poco" (en este ejemplo nada) en todos los registros.
Por lo tanto, si el planificador de JOINs tiene la opción de usar uno de estos dos índices, preferirá el de artículo.

Nota: Un índice por EMPRESA+ARTICULO también tendra estadística = 0,25, indicando que "se repite poco" (en este ejemplo nada) en todos los registros.

Creo que estás haciendo el SQL de forma incorrecta.
Si no quieres filtrar por municipio, debes eliminar esa línea del WHERE.

Código SQL [-]
select p.codigo, p.nombre, coalesce(sum(r.votos), 0) votos, coalesce(n.electos, 0) electos, n.circunscripcion,
       po.nombre
from partidos p
join resultados r on r.partido = p.codigo and p.codprv = r.codprv
join mesas m on m.codprv = r.codprv and m.codigo = r.mesa
join poblacion po on p.codprv = po.codprv and m.municipio = po.codigo
left join numelectos n on r.codprv = n.codprv and r.proceso = n.proceso and n.tipo = 'M' and r.partido = n.partido and po.codigo = n.circunscripcion
where
p.codprv = 13 and
r.proceso = 42 
/* and m.municipio = 175 Muestra todos los municipios */ 
group by p.codigo, p.nombre, electos, n.circunscripcion, po.nombre
order by po.nombre, 3 /*votos*/ desc, 4 /*electos*/ desc, p.nombre

Suposición 1 - Agregas lo que mencionas al WHERE.
Si haces lo que que mencionas, estarás diciendo que muestre los registros donde el municipio de la mesa sea el municipio de la poblacion.
Esto ya está garantizado por los JOINs
join mesas m on m.codprv = r.codprv and m.codigo = r.mesa
join poblacion po on p.codprv = po.codprv and m.municipio = po.codigo

Solo le estarás complicando la vida al planificador.

Código SQL [-]
select p.codigo, p.nombre, coalesce(sum(r.votos), 0) votos, coalesce(n.electos, 0) electos, n.circunscripcion,
       po.nombre
from partidos p
join resultados r on r.partido = p.codigo and p.codprv = r.codprv
join mesas m on m.codprv = r.codprv and m.codigo = r.mesa
join poblacion po on p.codprv = po.codprv and m.municipio = po.codigo
left join numelectos n on r.codprv = n.codprv and r.proceso = n.proceso and n.tipo = 'M' and r.partido = n.partido and po.codigo = n.circunscripcion
where
p.codprv = 13 and
r.proceso = 42 
/* Muestra todos los municipios */ 
and m.municipio = po.codigo 
group by p.codigo, p.nombre, electos, n.circunscripcion, po.nombre
order by po.nombre, 3 /*votos*/ desc, 4 /*electos*/ desc, p.nombre


Suposición 2 - Quitas "m.municipio = po.codigo" del JOIN .
Si haces esto, estás cambiando los datos sobre los que haces los cálculos.
En ese caso, si tenemos en cuenta solo las tablas MESAS y POBLACION sería
Código SQL [-]
/* Original */
mesas m 
join poblacion po on p.codprv = po.codprv and m.municipio = po.codigo

/* Tu modificacion */
mesas m 
join poblacion po on p.codprv = po.codprv /*and m.municipio = po.codigo*/

En este caso cada mesa se uniría con todas las poblaciones y tendrías muchísimos registros más.
Prueba estos SQL:
Código SQL [-]
/* Esto te devuelve las mesas y su municipio*/
/* Devuelve 738 registros para la provincia 13 */
select m.codprv, m.codigo, m.municipio, po.codigo, po.nombre
from mesas m
join poblacion po on m.codprv = po.codprv and m.municipio = po.codigo
where
m.codprv = : prvins
order by m.codprv, m.codigo, m.municipio, po.codigo, po.nombre
Código SQL [-]
/* Esto te devuelve las mesas unidas a cada municipio (aunque no le corresponda) */
/* ATENCION - TARDARÁ MUCHO Y DEVOLVERA MILES DE REGISTROS */
/* Registros = 738 mesas x 58.655 poblaciones = 42.287.390 registros*/
select m.codprv, m.codigo, m.municipio, po.codigo, po.nombre
from mesas m
join poblacion po on m.codprv = po.codprv /* and m.municipio = po.codigo*/
where
m.codprv = : prvins
order by m.codprv, m.codigo, m.municipio, po.codigo, po.nombre

Última edición por duilioisola fecha: 14-11-2023 a las 20:01:47.
Responder Con Cita
  #6  
Antiguo 16-11-2023
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
Muchísimas gracias. Tus explicaciones me enseñan muchas cosas que desconozco.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
a vueltas con los servidores de datos anubis Varios 11 13-01-2010 09:37:42
Dando vueltas con las capas CHiCoLiTa Providers 0 24-01-2006 12:09:55
Dandolo vueltas a un indice gario Oracle 0 17-03-2005 14:04:47


La franja horaria es GMT +2. Ahora son las 19:32:49.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi