Cita:
Empezado por lbuelvas
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
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.