martes, 3 de mayo de 2011

como no debe hacerse un query.


En esta ocasión podemos analizar otra pieza de código la cual requiere un análisis para determinar los problemas que ocasiona programar de esta manera. este es otro ejemplo de código el cual tiene practicas que impiden que la velocidad de ejecución sea óptima.








/**
* Fills the PreparedStatement with its respective values
* @param pstmt
* @param request
* @return
*/
public PreparedStatement setQueryvalues(PreparedStatement pstmt, HttpServletRequest request) {
try {
String search = request.getParameter("search") != null ? request.getParameter("search") : "";
log.debug("search = " + search);
//Check if there is any filter to search
if (search.equals("search")) {
String lang = request.getParameter("lang") == null ? "" : request.getParameter("lang");
String pid = request.getParameter("id") == null ? "" : request.getParameter("id");
String pname = request.getParameter("name") == null ? "" : request.getParameter("name");
log.debug("lang --> " + lang);
log.debug("pid --> " + pid);
log.debug("name --> " + pname);
request.setAttribute("id", pid);
request.setAttribute("name", pname);
request.setAttribute("search", search);
if (pid != null && !pid.equals("")) {
pstmt.setString(1, "%" + pid);
} else {
pstmt.setString(1, "%" + pid);
}
if (pname != null && !pname.equals("")) {
if (lang.equals("")) {
pstmt.setString(2, "%" + pname.toUpperCase() + "%");

/*
en este caso la cadena lang viene con el valor %, y el query viene más o menos así:
select * from tabla where valor1 like ? and valor2 like ? and valor3 like ?
pero que pasa si al parametro le pasamos un wildcard "%"
este queda así:
select * from tabla where valor1 like 'valor1' and valor2 like 'valor2' and valor3 like '%'
lo cual forza al query a regresar todos los valores haciendo una comparación tanto inútil,
esto sobrecarga la base de datos y evita que se optimizen los tiempos de busqueda

el mismo resultado puede lograrse con:
select * from tabla where valor1 like 'valor1' and valor2 like 'valor2'
permitiendo que la base de datos busque solo con los criterios de búsqueda necesarios
evitando así una sobrecarga.

*/

pstmt.setString(3, "%");
} else {
pstmt.setString(2, "%");
pstmt.setString(3, "%" + pname.toUpperCase() + "%");
}
} else {
pstmt.setString(2, "%");
pstmt.setString(3, "%");
}
} else {

/*
en este caso tenemos mas problemas al hacer que todos los parámetros
de búsqueda sean wildcards, esto hace una búsqueda con like por toda la
tabla y si el query trae un join esto alenta los resultados

*/

pstmt.setString(1, "%");
pstmt.setString(2, "%");
pstmt.setString(3, "%");
}

} catch (Exception e) {


/*
este antipatron ha sido explicado anteriormente como ocultamiento de excepciones,
este impide depurar correctamente el código para poder encontrar una excepción caso de ocurrir.

*/

e.printStackTrace();
}
return pstmt;
}



No hay comentarios: