Foros del Web » Programación para mayores de 30 ;) » Java »

Optimización de consultas a bbdd

Estas en el tema de Optimización de consultas a bbdd en el foro de Java en Foros del Web. Buenos días, Estoy realizando una aplicación escritorio en la que ejecuto un consulta muy parecida unas cuantas veces, del siguiente modo: Ventana principal: @import url("http://static.forosdelweb.com/clientscript/vbulletin_css/geshi.css"); ...
  #1 (permalink)  
Antiguo 08/09/2010, 08:02
 
Fecha de Ingreso: julio-2010
Mensajes: 104
Antigüedad: 13 años, 9 meses
Puntos: 2
Optimización de consultas a bbdd

Buenos días,

Estoy realizando una aplicación escritorio en la que ejecuto un consulta muy parecida unas cuantas veces, del siguiente modo:

Ventana principal:

Código java:
Ver original
  1. claseConsulta.metodoQuery(Connection conexion, parametros);

claseConsulta:
Código java:
Ver original
  1. public variable metodoQuery(Connection conexion, parametros){
  2.      
  3.        try {
  4.             if (conexion == null || conexion.isClosed()) {
  5.                 conexion = conexionPG.reConectar();
  6.             }
  7.         } catch (SQLException ex) {
  8.             log.error(ex);
  9.         }
  10.  
  11.         //Construyo la query        
  12.         String select = "select distinct campo1,  ";
  13.         consulta = consulta + select;
  14.  
  15.         String campo2 = " campo2, ";
  16.         consulta = consulta + campo2;
  17.  
  18.  
  19.         String campo3 = " campo3, ";
  20.         consulta = consulta + campo3;
  21.  
  22.         String from = "from tabla";
  23.         consulta = consulta + from;
  24.  
  25.         String whereC1 = "where campo1 like 'parametros.parametro1' ";
  26.         consulta = consulta + whereC1;
  27.  
  28.         String whereC4 = "and campo4 like 'parametros.parametro2'' ";
  29.         consulta = consulta + whereC4;
  30.  
  31.        try {
  32.  
  33.             PreparedStatement ps = conexion.prepareStatement(consulta);
  34.  
  35.             rs = ps.executeQuery();
  36.  
  37.         } catch (SQLException ex) {
  38.             log.error("daoAlertas\n", ex);
  39.         }
  40.  
  41.         if (rs != null) {
  42.             return rs;
  43.         }
  44.  
  45.         return null;
  46.  
  47. }

Creo que lo más eficiente sería que algunos de los string que forman la consulta se convirtieran en una constante o un valor que me devolviera un método.

¿Cuál de las tres opciones es la óptima?

Un saludo y buen día.
  #2 (permalink)  
Antiguo 08/09/2010, 13:24
Avatar de Xerelo  
Fecha de Ingreso: mayo-2009
Mensajes: 2.175
Antigüedad: 15 años
Puntos: 306
Respuesta: Optimización de consultas a bbdd

No acabo de entender tu pregunta, pero estás desperdiciando el prepareStatement

http://www.forosdelweb.com/f45/difer...tement-612469/
  #3 (permalink)  
Antiguo 09/09/2010, 00:45
 
Fecha de Ingreso: julio-2010
Mensajes: 104
Antigüedad: 13 años, 9 meses
Puntos: 2
Respuesta: Optimización de consultas a bbdd

Buenos días,

Gracias por la indicación.

En la clase consulta tengo varios métodos metodoQuery que se diferencian muy poco entre unos y otros como por ejemplo metodoQuery de la primera pregunta y el que viene a continuación:

Código java:
Ver original
  1. public variable metodoQueryParecido(Connection conexion, parametros){
  2.      
  3.        try {
  4.             if (conexion == null || conexion.isClosed()) {
  5.                 conexion = conexionPG.reConectar();
  6.             }
  7.         } catch (SQLException ex) {
  8.             log.error(ex);
  9.         }
  10.  
  11.         //Construyo la query        
  12.         String select = "select distinct campo1,  ";
  13.         consulta = consulta + select;
  14.  
  15.         String campo2 = " campo2, ";
  16.         consulta = consulta + campo2;
  17.  
  18.         //antes campo3, ahora campo4
  19.         String campo4 = " campo4, ";
  20.         consulta = consulta + campo4;
  21.  
  22.         String from = "from tabla";
  23.         consulta = consulta + from;
  24.  
  25.         String whereC1 = "where campo1 like 'parametros.parametro1' ";
  26.         consulta = consulta + whereC1;
  27.  
  28.         //antes campo4, ahora campo2
  29.         String whereC2 = "and campo2 like 'parametros.parametro2'' ";
  30.         consulta = consulta + whereC2;
  31.  
  32.        try {
  33.  
  34.             PreparedStatement ps = conexion.prepareStatement(consulta);
  35.  
  36.             rs = ps.executeQuery();
  37.  
  38.         } catch (SQLException ex) {
  39.             log.error("daoAlertas\n", ex);
  40.         }
  41.  
  42.         if (rs != null) {
  43.             return rs;
  44.         }
  45.  
  46.         return null;
  47.  
  48. }

Lo que estoy probando ahora es a transformar los métodos del siguiente modo:

metodoQuery
Código java:
Ver original
  1. public variable metodoQuery(Connection conexion, parametros){
  2.      
  3.         conexion = conexion();
  4.  
  5.         //Construyo la query        
  6.          consulta += query.select();
  7.  
  8.         consulta += query.distinct();
  9.  
  10.         consulta += query.campo123();
  11.  
  12.         consulta += query.from();
  13.  
  14.         consulta += query.whereC1(parametros.parametro1);
  15.  
  16.         consulta += query.wherec4(parametros.parametro2);
  17.  
  18.        try {
  19.  
  20.             PreparedStatement ps = conexion.prepareStatement(consulta);
  21.  
  22.             rs = ps.executeQuery();
  23.  
  24.         } catch (SQLException ex) {
  25.             log.error("daoAlertas\n", ex);
  26.         }
  27.  
  28.         if (rs != null) {
  29.             return rs;
  30.         }
  31.  
  32.         return null;
  33.  
  34. }


query
Código java:
Ver original
  1. public class query {
  2.  
  3.     public static String select() {
  4.         return "select ";
  5.     }
  6.  
  7.     public static String distinct() {
  8.         return "distinct ";
  9.     }
  10.    
  11.     public static String from() {
  12.         return "from tabla ";
  13.     }
  14.  
  15.      public static String where() {
  16.         return "where ";
  17.     }
  18.  
  19.     public static String campo123() {
  20.         return "campo1, campo2, campo3 ";
  21.     }
  22.  
  23.     public static String campo12() {
  24.         return "campo1, campo2, ";
  25.     }
  26.  
  27.     public static String campo4() {
  28.         return "campo4 ";
  29.     }
  30.  
  31.     public static String fromTabla() {
  32.         return "from tabla";
  33.     }
  34.  
  35.     public static String whereC1(String param) {
  36.         return "C1 = " + param + " ";
  37.     }
  38.  
  39.     public static String whereC1(String param) {
  40.         return "and C2 = " + param + " ";
  41.     }
  42.  
  43.     public static String whereC1(String param) {
  44.         return "and C4 = " + param + " ";
  45.     }
  46.  
  47.     public static String whereC3(String param) {
  48.         return "and C3 = " + param + " ";
  49.     }

Y después de estas tres mil líneas de código mi duda es si lo dejo como estaba, lo cambio a la llamada a métodos o sustituyo los métodos por constantes.

Un saludo y buen día.
  #4 (permalink)  
Antiguo 09/09/2010, 11:51
Avatar de francopai  
Fecha de Ingreso: agosto-2008
Mensajes: 42
Antigüedad: 15 años, 8 meses
Puntos: 2
Respuesta: Optimización de consultas a bbdd

No logro entender cual es tu duda, pero te cuento que la idea es simple. Para armar una query "dinamica", osea que en algunos casos se utilicen ciertos parametros y en otros no, la idea es concatenar String hasta lograr la query final y una vez que tenes la query en un String, instancias tus objetos que conectan con la Base de Datos y le pasas la consulta.
Un saludo
  #5 (permalink)  
Antiguo 09/09/2010, 12:00
Avatar de juamd  
Fecha de Ingreso: marzo-2009
Ubicación: Bogotá
Mensajes: 285
Antigüedad: 15 años, 1 mes
Puntos: 8
Respuesta: Optimización de consultas a bbdd

Que tal !!!

En la empresa donde trabajo usamos una clase llamada Sql, en la cual vas agregando parametros dependiendo del tipo de consulta que quieras armar, el caso es que siempre la armas igual. La clase puede ser algo como esto:

Código:
package Persistencia;

import java.util.Vector;

public class Sql {

    private Vector colCondiciones = new Vector();
    private Vector colCampos = new Vector();
    private Vector colTablas = new Vector();
    private Vector colValues = new Vector();
    private Vector colJoin = new Vector();
    private Vector colGroup =  new Vector();
    private Vector colOrderBy = new Vector();
    private String funcion = "";


    public void addCondicion(String condicion)
    {
        if(!this.colCondiciones.contains(condicion)){
            this.colCondiciones.add(condicion);
        }
    }
    
    public void addCampo(String campo)
    {
        if(!this.colCampos.contains(campo)){
            this.colCampos.add(campo);
        }
    }

    public Vector getCampos() {
        return this.colCampos;
    }
    
    public void addTabla(String tabla)
    {
        if(!this.colTablas.contains(tabla)){
            this.colTablas.add(tabla);
        }
    }

    public void addValue(String valor)
    {
        //Cuando se pasa un String este valor debe compararse en la base de datos entre comillas simples
        valor = "'"+valor +"'";
        //if(!this.colValues.contains(valor)){
            this.colValues.add(valor);
        //}
    }

    public void addValue(int valor)
    {
        //if(!this.colValues.contains(valor)){
            this.colValues.add(valor);
        //}
    }

    public void addValue(double valor)
    {
        //if(!this.colValues.contains(valor)){
            this.colValues.add(valor);
        //}
    }

    public void addJoin(String valor)
    {
        if(!this.colJoin.contains(valor)){
            this.colJoin.add(valor);
        }
    }

    public void addGroup(int numero)
    {
        this.colGroup.add(String.valueOf(numero));
    }

    public void addOrderBy(int numero)
    {
        this.colOrderBy.add(String.valueOf(numero));
    }

    public void setFuncion(String funcion)
    {
        this.funcion = funcion;
    }

    /**
     * Se recorre cada Vector y se van agregando sus campos a la cadena respectiva separados por ",". Se revisa que
     * el elemento no sea el ultimo, es decir el elemento en la posicion que esta en el tamaño del vector - 1 (en los
     * vectores los elementos van de 0 hasta el tamaño -1) ya que a este no se le puede agregar la ",".
     * */
    public String generar()
    {
        String consulta = "", campos = "", tablas = "", condiciones = "", values = "", 
                joins = "", group = "", order = "";
        int i;

        if(this.colCampos.size() > 0){
            for(i = 0; i < this.colCampos.size(); i++){
                campos = campos + this.colCampos.get(i);
                if(i != (this.colCampos.size() - 1)){
                    campos = campos + ",";
                }
            }
        }
        
        if(this.colTablas.size() > 0){
            for(i = 0; i < this.colTablas.size(); i++){
                tablas = tablas + this.colTablas.get(i);
                if(i != (this.colTablas.size() - 1)){
                    tablas = tablas + ",";
                }
            }
        }

        if(this.colCondiciones.size() > 0){
            for(i = 0; i < this.colCondiciones.size(); i++){
                condiciones = condiciones + this.colCondiciones.get(i);
                if(i != (this.colCondiciones.size() - 1)){
                    condiciones = condiciones + " and ";
                }
            }
            condiciones = " where " + condiciones;
        }

        if(this.colValues.size() > 0){
            for( i = 0; i < this.colValues.size(); i++){
                values = values + this.colValues.get(i);
                if(i != (this.colValues.size() - 1)){
                    values = values + ",";
                }
            }
        }

        if(this.colJoin.size() > 0){
            for( i = 0; i < this.colJoin.size(); i++){
                joins = joins + this.colJoin.get(i) + " ";
            }
            condiciones = " " + joins + " " + condiciones;
        }

        if(this.colGroup.size() > 0) {
            group = "group by ";
            for(i=0; i<this.colGroup.size(); i++){
                group = group + this.colGroup.get(i);
                if( i != (this.colGroup.size() - 1)){
                    group = group + ",";
                }
            }
            condiciones = condiciones + " " +group;
        }

        if(this.colOrderBy.size() > 0){
            order = "order by ";
            for(i=0; i<this.colOrderBy.size(); i++){
                order = order + this.colOrderBy.get(i);
                if( i != (this.colOrderBy.size() - 1)){
                    order = order + ",";
                }
            }
            condiciones = condiciones + " " + order;
        }


        if(this.funcion.equals("insert")){
                consulta = this.funcion + " into " + tablas + "( " + campos + " ) " + " values( " + values + " ) ";
        }else if(this.funcion.equals("update")) {
            consulta = this.funcion + " " + tablas + " set " + campos + condiciones;
        }else if(this.funcion.equals("delete")){
            consulta = this.funcion + " from " + tablas + condiciones;
        }else if(this.funcion.equals("select")){
            if(this.colTablas.size() > 0){
                consulta = "select " + campos + " from " + tablas + condiciones;
            }else{
                consulta = "select " + campos;
            }
        }else if(this.funcion.equals("insert_select")){
            if(this.colGroup.size() > 0){
                consulta = "insert into "+this.colTablas.get(0)+" select "+campos+ " from "+this.colTablas.get(1)+condiciones;
            }else{
                consulta = "insert into "+this.colTablas.get(0)+" select "+campos+ " from "+this.colTablas.get(1);
            }


        }else {
            consulta = this.funcion;
        }
        
        return consulta;
        
    }

    /**
     * Se usa para eliminar lo que tenga el objeto almacenado a fin de realizar una nueva consulta
     */
    public void resetConsulta()
    {
        this.colCampos.clear();
        this.colCondiciones.clear();
        this.colJoin.clear();
        this.colTablas.clear();
        this.colValues.clear();
        this.colGroup.clear();
        this.colOrderBy.clear();
        this.funcion = "";
    }
como se puede ejecutar todo esto ? puede ser algo como esto:

Código:
public static string actualizarEmpleado(double cedula,String centro,String cargo, double basico, String fecha){
        sql.resetConsulta();

        sql.setFuncion("update");
        sql.addTabla("empleados");

        sql.addCampo("seccionEmpleado = '"+centro+"'");
        sql.addCampo("cargoEmpleado = '"+cargo+"'");
        sql.addCampo("basicoMensualEmpleado ="+basico);
        sql.addCampo("fechaTerminoContratoEmpleado ='"+fecha+"'");
        sql.addCondicion("cedulaEmpleado = "+cedula);

        return sql.generar;
    }
Supongamos que el metodo actualizar empleado te retorna la consulta necesaria para realizar esa accion en la base de datos, asi seria la forma de armar la consulta de esa manera.


Saludos.
  #6 (permalink)  
Antiguo 10/09/2010, 00:49
 
Fecha de Ingreso: julio-2010
Mensajes: 104
Antigüedad: 13 años, 9 meses
Puntos: 2
Respuesta: Optimización de consultas a bbdd

Buenos días,

#francopai: Muchas gracias por la indicación. Eso ya lo estoy haciendo, lo que quiero es saber la manera óptima de hacerlo, es decir, la más rápida, legible y manejable.

#juamd: Te agradezco que te hayas tomado el tiempo de mostrarme la clase con la que trabajas, no es lo que busco en estos momentos pero seguro que me vale en un futuro.

Siento no haberme explicado del modo correcto.

Lo que ya tenía hecho: método en el que vas concatenando sentencias a un string y al final con ese string y una connection:

Código java:
Ver original
  1. Statement st = conexion.createStatement();
  2.  
  3. rs = st.executeQuery(consulta);

Lo que estoy probando:método en el que la unica diferencia con el anterior es que en vez de

Código java:
Ver original
  1. consulta += "select campo from tabla"

hago...

Código java:
Ver original
  1. public class consulta {
  2.      consulta += query.select();
  3.      consulta += query.campo();
  4.      consulta += query.from ();
  5.      consulta += query.tabla();
  6. }
  7.  
  8. public class query {
  9.  
  10.     public static String select() {
  11.         return "select ";
  12.     }
  13.    
  14.     public static String from() {
  15.         return "from ";
  16.     }
  17.  
  18.     public static String campo() {
  19.         return "campo ";
  20.     }
  21.  
  22.     public static String tabla() {
  23.         return "tabla ";
  24.     }
  25.  
  26. }

Lo que no se si haré:en vez de llamar a un método de otra clase, llamaré a un properties.

Un saludo y buen día.

Etiquetas: bbdd, consulta, optimización, query, sql, tunning
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 05:06.