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 21-11-2019
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.911
Poder: 25
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
Cita:
Empezado por lbuelvas Ver Mensaje
utilizar LEFT JOIN en lugar de INNER JOIN
No, eso no esta bien. Eso altera los resultados (semantica diferente!)
__________________
El malabarista.
Responder Con Cita
  #2  
Antiguo 21-11-2019
[egostar] egostar is offline
Registrado
 
Registrado: feb 2006
Posts: 6.557
Poder: 25
egostar Va camino a la fama
Cita:
Empezado por mamcx Ver Mensaje
No, eso no esta bien. Eso altera los resultados (semantica diferente!)
Ciertamente....


__________________
"La forma de empezar es dejar de hablar y empezar a hacerlo." - Walt Disney
Responder Con Cita
  #3  
Antiguo 21-11-2019
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.044
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por egostar Ver Mensaje
Ciertamente....
Muy bueno
Responder Con Cita
  #4  
Antiguo 22-11-2019
lbuelvas lbuelvas is offline
Miembro
 
Registrado: may 2003
Ubicación: Colombia
Posts: 377
Poder: 22
lbuelvas Va por buen camino
Ya hicieron la prueba ? Si la llave foránea es "not null" funciona como un inner join. Sigo trabajando con bases de datos Firebird 1.5 y el preprocesador (el que define el plan de la consulta) no selecciona algunos índices como uno esperaría. Mis consultas funcionan como espero que funcionen. En Firebird 3 he tratado de usar inner join pero si no toma el índice que espero paso a usar left join siempre y cuando la llave foránea tenga valor (definiéndola not null). Lo que pasa es que trabajo casi exclusivamente con Interbase y luego Firebird desde el año 1998. Firebird 1.5 es suficiente para todo, pero ahora Windows 10 cada vez que hace una actualización importante desinstala el motor de base de datos por el defecto que tiene el instalador de Firebird 1.5 que el Applet que se adiciona al panel de control hace que éste cuando se abre se cierra inmediatamente. Para instalar Firebird 1.5 toca cambia el nombre del instalador pero de tanto en tanto Windows 10 lo desinstala. Estoy moviéndome a Firebird 3 pero los componentes IBX no van bien con este motor por lo que adquirí UniDac y estamos pasando de VCL a uniGui y de IBX a uniDac.
__________________
Luis Fernando Buelvas T.
Responder Con Cita
  #5  
Antiguo 22-11-2019
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.044
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por lbuelvas Ver Mensaje
Estoy moviéndome a Firebird 3 pero los componentes IBX no van bien con este motor...
¿En qué no van bien?
Responder Con Cita
  #6  
Antiguo 22-11-2019
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.911
Poder: 25
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
Cita:
Empezado por lbuelvas Ver Mensaje
Ya hicieron la prueba ?
Si la llave foránea es "not null" funciona como un inner join.
Estas "abusando" del comportamiento interno, pero es semántica errónea. Al ver con LEFT uno asume que hay nulos. Eso es lo que dice el codigo.

Cita:
Empezado por lbuelvas Ver Mensaje
Sigo trabajando con bases de datos Firebird 1.5 y el preprocesador (el que define el plan de la consulta) no selecciona algunos índices como uno esperaría. Mis consultas funcionan como espero que funcionen. En Firebird 3 he tratado de usar inner join pero si no toma el índice que espero paso a usar left join siempre y cuando la llave foránea tenga valor (definiéndola not null).
Aquí hay un error de apreciación de cómo funcionan los motores de BD. De entrada, hay que dudar MUCHISIMO que un motor mas nuevo sea menos eficiente que el mas viejo.

Ni te imaginas lo mucho que ha avanzado el tema de los RDBMS estos años. Y esos avances están siendo aplicados constantemente. Los RDBMs son MUY competitivos entre ellos.

---

No siempre elegir un indice es lo mejor.

Una de las tareas del query planer es determinar la manera menos costosa de ejecutar la consulta. Si este determina que usar el indice trae un mayor costo, lo DESCARTA.

Ahora, es posible que este se "equivoque?". Si. Y es posible que DIO LA CASUALIDAD que en la version vieja no cometa el error y en la nueva sí? Claro. Y eso significa que es mejor usar la vieja? NOOOOOOOO.

Porque es MUY probable que la nueva manifieste un ERROR de logica y/o diseño que la vieja, por casualidad NO VE.

Asi que:
  • Usa la version(estable) mas nueva del motor siempre. Eso te dara de "gratis" todo lo que lo nuevo traiga y este estara compilado con las mejores que hay en lo mas nuevo (como soporte a SIMD).
  • Ejecuta la consulta que quieres. Sea que use o no indices, si esta se ejecuta rapido entonces paras.
  • Si ves un problema, es porque hay un problema en el codigo! Que es:
  • Como le estas diciendo LEFT JOIN en vez de INNER JOIN le estas diciendo al query planer que es MAS COSTOSO UNIR AMBAS TABLAS. Inner join es MUCHO más eficiente de ejecutar. Lo se, estoy armando un lenguaje relacional y la implementación del inner join es pan comido, y cada otro es mas y mas complejo.
  • Estas metiendo una condición que hace ineficiente el uso de indices. Al 100% esta en los wheres o los group by, o lo anulas con un sort. Pero los wheres es mas común. Si necesitas ejecutar una expresión, indexa por esta: https://firebirdsql.org/rlsnotesh/in...xpression.html
  • Una mala configuracion del motor pudiera ser el problema. Si el motor esta bajo precion (por estar configurado de forma negativa versus su entorno de hardware, ej: Falta de memoria) entonces puede verse forzado a optimizar por bajo recursos vs velocidad
  • Luego de mover mucho la BD (ej: un insert masivo, o grandes cambios en la estructura) las estadisticas se pueden desbalancear. Firebird usa estadisticas para ESTIMAR los costos. Si estas estan mal, puede pensar que la tabla es "pequeña" donde meter indices es bobada. Resetea: http://www.firebirdfaq.org/faq110/
  • Por ultimo, puedes decirle al motor que deje de fumarsela y que tu REALMENTE sabes mas: Fuerza al query planer a hacer lo que tu dices: http://www.firebirdfaq.org/faq224/

Pero en toda mi vida, usando como 8 rdbms diferentes solo he tenido que forzar a Mysql (que en versiones antes tenia el query planer mas imbecil del mundo. Todos los join era nested loops, que asco!) y aun asi, termine reescribiendo el query mejor. Siempre sigue estos pasos:
  • Haz que funciones
  • Hazlo correcto
  • Hazlo rapido
Y en el caso de compiladores eficientes como SQL, los 2 primeros pasos logran el tercero.
__________________
El malabarista.
Responder Con Cita
  #7  
Antiguo 22-11-2019
novato_erick novato_erick is offline
Miembro
 
Registrado: ago 2010
Ubicación: Panamá
Posts: 396
Poder: 14
novato_erick Va por buen camino
Cita:
Empezado por Casimiro Notevi Ver Mensaje
Muy bueno
Ciertamente Si...

egostar, Casimiro, mamcx es un gran privilegio que lean mi post ayudadome como siempre.. Bendiciones Totales....



Por cierto uso el inner join porque se que cada fila de la tabla A exista una fila en la tabla B. bueno en teoría.


Provaré la sugerencia de lbuelvas del uso del CAST..

Saludos y les informo
Responder Con Cita
  #8  
Antiguo 22-11-2019
novato_erick novato_erick is offline
Miembro
 
Registrado: ago 2010
Ubicación: Panamá
Posts: 396
Poder: 14
novato_erick Va por buen camino
Descartado funcion CAST en Campo TimesTamp

La verdad como había mostrado dos resultado de respuesta a mi consulta en Base de datos de Desarrollo y la misma en producción obteniendo resultado lento en la de producción mas no en la de Desarrollo descarto totalmente el campo fecha como causa sugerido por nuestro compañero lbuelvas.

aun me encuentro en pruebas. Agregué el script solicitado por ustedes.

Saludos;
Responder Con Cita
  #9  
Antiguo 22-11-2019
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.044
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Otra cosa a tener en cuenta y que es más importante de lo que puedas pensar, usa dominios.
De siempre, en todos los campos, usar dominios.

Código Delphi [-]
CREATE DOMAIN DOMANO AS smallint NOT NULL;
CREATE DOMAIN DOMCODIGO AS integer;
CREATE DOMAIN DOMFECHA AS timestamp;
CREATE DOMAIN DOMHORA AS timestamp;
...

CREATE TABLE TBCABECERASALBARANESVENTAS
(
  CODIGO DOMCODIGONONULO,
  ANO DOMANO,
  TIPODOCUMENTO DOMTIPODOCUMENTO NOT NULL,
  SERIE DOMSERIE,
  NUMERO DOMCODIGONONULO,
  FECHA DOMFECHA,
  HORA DOMHORA,
Responder Con Cita
  #10  
Antiguo 23-11-2019
lbuelvas lbuelvas is offline
Miembro
 
Registrado: may 2003
Ubicación: Colombia
Posts: 377
Poder: 22
lbuelvas Va por buen camino
Hola, me alegra que se haya dado la discusión. Gracias por las recomendaciones sobre el uso de Inner Join, voy a revisar una parte de un proyecto actual donde en las pruebas generé 1.00.000 de registros en dos tablas que están relacionadas 1:M.

Colocaré los resultados para continuar con el tema que se me hace interesante, por eso respondí tan pronto el compañero escribió su inquietud.

Revisaré mañana el script y espero que mis comentarios sean de ayuda.

Un abrazo para todos.
__________________
Luis Fernando Buelvas T.
Responder Con Cita
  #11  
Antiguo 23-11-2019
novato_erick novato_erick is offline
Miembro
 
Registrado: ago 2010
Ubicación: Panamá
Posts: 396
Poder: 14
novato_erick Va por buen camino
Cita:
Empezado por Casimiro Notevi Ver Mensaje
Otra cosa a tener en cuenta y que es más importante de lo que puedas pensar, usa dominios.
De siempre, en todos los campos, usar dominios.

Interesante Casimiro Notevi nunca me pareció relevante usar los dominios en fin será porque en la teoría normalmente se lo dejo al motor de base de datos
En este caso según usar dominion en Firebird no son los tipos de datos estándar sino los creados por el programador la para cubrir sus propias necesidades. al principio mi necesidad fue simplemente usar tipos de Datos que normalmente están en el motor.

En fin ahora quedé con la duda 'Perdonen mi ignorancia' del uso del dominio a la hora de realizar consulta anidadas de diferentes tablas.


Saludos a todos;

novato_erick
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
Consulta update desde una consulta select jafera SQL 3 08-05-2015 19:56:02
Consulta SQL basada en otra consulta anterior jafera SQL 5 19-11-2013 01:07:37
Optimizando velocidad de mis páginas lucasarts_18 PHP 2 25-09-2008 19:42:47
Optimizando Creación de Formularios MDI nelostanley OOP 20 08-01-2008 03:00:36
Realizar una consulta sobre los registros que devuelve otra consulta Borjaserrano Firebird e Interbase 12 01-10-2007 23:19:44


La franja horaria es GMT +2. Ahora son las 18:58:26.


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