Sub-consultas VS FOR ALL ENTRIES

sap-abap
Etiquetas: #<Tag:0x00007f5ca1554d30>

#1

Hola @Abapers,

Quisiera que me den sus opiniones sobre que tipo de consulta tiene mejor performance.
Ya hice las pruebas pero quiero escuchar opiniones y diferentes puntos de vista.

Aquí un ejemplo:

SUBQUERY

SELECT * FROM SFLIGHT AS F INTO TABLE T_FLIGHT
    WHERE SEATSOCC < F~SEATSMAX
      AND EXISTS ( SELECT * FROM SPFLI
                     WHERE CARRID = F~CARRID
                       AND CONNID = F~CONNID
                       AND CITYFROM = 'FRANKFURT'
                      AND CITYTO = 'NEW YORK'  )
      AND FLDATE BETWEEN '19990101' AND '19990331'.

FOR ALL ENTRIES:

SELECT * FROM SPFLI
  INTO TABLE T_SPFLI
  WHERE CITYFROM = 'FRANKFURT'
    AND CITYTO = 'NEW YORK'.

CHECK T_SPFLI[] IS NOT INITIAL.
SELECT * FROM SFLIGHT
    INTO TABLE T_SFLIGHT
    FOR ALL ENTRIES IN T_SPFLI
    WHERE SEATSOCC < F~SEATSMAX
      AND CARRID = T_SPFLI-CARRID
      AND CONNID = T_SPFLI-CONNID
      AND FLDATE BETWEEN '19990101' AND '19990331'.

** LET THEM FIGHT!!!**


#2

Y un inner join? XD :stuck_out_tongue:


#3

Ese es el ganador por excelencia jaja.


#4

Es que soy un Abap muy jovial en el mundo entonces no me planteo select anidados y un FOR ALL ENTRIES solo para casos puntuales, como norma uso INNER JOIN. (Los de mi empresa con muchos años de experiencia usan mucho el FOR ALL ENTRIES).


#5

Hiciste pruebas, cuales fueron tus resultados?
Creo que el punto fuerte del for all entries lo estan mal comparando, cuando el fuerte de esta sentencia es precisamente que te permite manipular la data antes de hacer la union.
Con el join no podrias hacer eso aunque quisieras, pero en velocidad el join es el estado natural de las consultas.


#6

Los resultados fueron:
Microsegundos.

Ya ustedes sabrán.


#7

Juraba que la sub consulta seria mas rapida, el for all antrie tiene los suyo tambien.


#8

quizas el for all entries es un poco mas rapido porque trabaja con una tabla interna y una tabla de diccionario y ahi puede que como tienes algo en menoria de ejecucion sea mas rapido…ahora, yo hubiese hecho el select sin el as, no se si por eso se tarde mas en sap nunca he trabajado una consulta asi !!


#9

Saludos @Haden_Yasser_

Excelente test.
En el For all entries. Si se cambia el BETWEEN por un rango y hacer un delete a la tabla interna, que tan rápido seria.

Sugerencias generales:

  1. El SELECT * no es recomendable
  2. Realiza un inner join para 2 tablas RELACIONADAS por las claves primarias TABLA_CABECERA y TABLA_DETALLE y el Where por campos las claves de TABLA_CABECERA.
  3. El BETWEEN no utilizar en un Select, Sugerencia un rango y realizar un Delete a TABLA_INTERNA.

Quizá es mas rápido, pero todo depende de las relación de las tablas, indices, etc.


#10

Yo también me inclinaría por el FOR ALL ENTRIES. La tentación de hacer una subquery es grande por la simplicidad de código ya que no hace falta una tabla interna ni hacer dos select pero el hecho de contar con datos en memoria interna creo que dan la clave.


#11

Bueno, Tomando en cuenta que soy novato y ando probado como hacer las cosas.

Me ha resultado muy conveniente el FOR ALL ENTRIES, porque he necesitado manipular datos antes de cargarlos.
Sin embargo, Traigo la inche logica de como hacia consultas en 4GL y pues a veces lo visualizo como sub-consultas, aquí en ABAP no me ha servido de mucho, incluso prefiero INNER JOIN antes que sub-consultas.

No puedo opinar como experto, porque aun no lo soy, pero comparto mis experiencias.:+1:

Saludos a todos.


#12

@Haden_Yasser_
Te comento que a mi entender hiciste lo que siempre recomendamos independientemente de las best-practices de SAP y de los ejemplos de la SE30.
Tuve varias experiencias con los ejemplos que mencionás y te voy a comentar algunas cosas como conclusión:

  1. Depende de la Base de datos, el Sistema Operativo y el Hard que tengas, no todos se comportan igual ante la misma consulta.
  2. En los ejemplos de SAP tenés que el FOR ALL ENTRIES funciona mejor siempre y cuando la tabla que hacés referencia tenga como máximo 100 registros, ellos mismos hacen particiones a esa Tabla interna y luego hacen APPEND, en caso contrario quizás entren en un loop infinito, ABAP no lo resuelve.
  3. Personalmente creo que la conclusión, independientemente que lo diga cualquier gurú, es hacer lo que hiciste, tomar el GET RUNTIME y luego compararlo. También podés hacer la prueba con EXECSQL para comparar, ya que en algunos casos y con Informix me era más conveniente hacer el EXEC ENDEXEC, Igualmente la prueba calculo que la habrás hecho en un entorno de DES o QAS. Creeme que también esos valores cambian en el entorno PRD.
    Espero haber sido claro.
    Exitos.

#13

Saludos @Haden_Yasser_ ,

En mi caso en el único momento en el que he usado For all entries y es porque es obligatorio es cuando quiero hacer Join con alguna tabla cluster. De lo contrario mi consulta normal utilizando inner join, left outer join, group by y/o having; Me ha funcionado perfectamente sin afectarme el rendimiento.

Todo dependerá de cómo estén relacionados los datos y cuán eficiente sea tu escritura de consultas. Por ejemplo. En este caso yo no utilizaría una sub-consulta, sino que haría un Join por los campos claves, hiciera las comparaciones de lugar y de esa misma forma, especificaría puntualmente los campos que necesito de la base de datos.

Espero te sirva de algo.


#14

La mejor respuesta dada.

Ningún Sistema es el mismo simplemente desde los ambientes Desarrollo, Calidad y Productivo son completamente diferentes.

Un “experto” me dijo, es que es tu lógica, no me ofende ni me ofendió, pero cuando se le dijo es tu lógica se hizo un hoya presto XD.

sin duda las consultas anidadas, no son la mejor opción en ningún MDB. Funcionan muy bien con tablas de muy pocos datos o cuando de plano te quieres quitar tablas y códigos extras y lo digo porque lo uso en SQL.

Para SAP que no se nada!, aquí los expertos su uso sin duda es For All Entries, les e solicitado el porque y no existen otras maneras y nunca dan respuesta, pero bueno ese es problema local :stuck_out_tongue:

Otro punto es que tengas los medios para testear lo que tus consultas consuman, actualmente nada se puede porque o no lo sabe el dichoso admin de sistemas, o porque SAP es perfecto… volví a lo mismo :stuck_out_tongue:, disculpen lo que pasa es que anterior mente nosotros mismos teste a vamos y realizábamos el análisis a fondo den performance y demas :see_no_evil: y que de la nada te digan que no se puede y aparte que es un $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ gastado pues nel no se vale XD.

y para rematar seria que “es que la logica depende de cada programa que hagas”.
Asi es, nada del codido se puede reutilizar como la mejor manera de extracción de datos o manipulacion :alien::tophat: los mejores iconos para representar este parrafo.

Saludos!


#15

@Neto :joy: disfruté tu publicación lol


#16

Buenas buenas, iba a escribir en este post hace un tiempo pero se me pasó :stuck_out_tongue:

Yo en mis comienzos también tenía ciertas dudas al respecto sobre las ventajas e inconvenientes de usar INNER JOIN vs FOR ALL ENTRIES (FAE). Me parecía que usar INNER JOIN era mejor que FAE ya que como el JOIN lo manejaba directamente el DBMS, él ya está optimizado para dicha labor. Pero con el tiempo (y cómo me comentaron mis compañeros del área de centro de soporte) comencé a ver más ventajas en FAE que las que me podía dar el INNER JOIN.

Una de ellas es la cantidad de registros no filtrados (consumo de memoria del servidor). Cuando se realiza un INNER JOIN entre dos tablas y luego se quiere realizar un filtro por alguno de los campos que no sea clave de ninguna de las tablas, la tabla resultante contiene absolutamente todos los registros, tanto los que deseas como los que no, y posteriormente tendrías que eliminarlos, con el consecuente consumo de memoria y tiempo.

Allí vamos a una segunda ventaja que es poder concatenar varias tablas realizando consultas parciales filtradas siempre sobre los campos claves de las tablas (aumento de rendimiento en tiempo considerable), además de poder paliar los efectos de la cantidad de registros en memoria del punto anterior.

Una tercera ventaja sería al momento de detectar errores (por campos vacíos por ejemplo) que evita que el INNER JOIN se haga correctamente y son difíciles de detectar si se tratan de miles de registros (y peor si está incluída una tabla cluster (BSEG, te odio!!)). Al realizar un conjunto de FAE se podría evaluar cada resultado parcial y detectar y filtrar esos casos indeseados.

Como acotación, he de mencionar que buenas amigas de las FAE son las tablas con índices auxiliares, ya que con eso garantizas velocidad de acceso y un mejor filtrado de la información a procesar.

Esos son los que se me ocurren ahorita (tengo sueño), espero pueda servir de utilidad dicha info :thumbsup:


#17

Cosas que en cualquier otro MBD no pasa, que puedes detectar con mayor facilidad o que puedes controlar mas fácilmente, que seria casi lo mismo.


#18

As de querer conocer a los consultores verdad :joy:


#19