java - preparedstatement - ResultSet: recuperación de valores de columna por índice versus recuperación por etiqueta
select en java (12)
¡Puedes tener lo mejor de ambos! La velocidad de uso de índices con el mantenimiento y la seguridad de usar nombres de columna.
Primero, a menos que esté realizando un bucle a través de un conjunto de resultados, simplemente use los nombres de las columnas.
Defina un conjunto de variables enteras, una para cada columna a la que accederá. Los nombres de las variables pueden incluir el nombre de la columna: por ejemplo, iLast_Name.
Antes del bucle de conjunto de resultados, itere a través de los metadatos de la columna y establezca el valor de cada variable entera en el índice de columna del nombre de columna correspondiente. Si el índice de la columna ''Last_Name'' es 3, entonces establezca el valor de ''iLast_Name'' en 3.
En el bucle de conjunto de resultados use los nombres de las variables enteras en los métodos GET / SET. El nombre de la variable es una pista visual para el desarrollador / mantenedor en cuanto al nombre real de la columna a la que se accede, pero el valor es el índice de la columna y proporcionará el mejor rendimiento.
NOTA: la asignación inicial (es decir, el nombre de la columna a la asignación de índice) solo se realiza una vez antes del ciclo en lugar de hacerlo para cada registro y columna del ciclo.
Cuando uso JDBC, a menudo me encuentro con constructos como
ResultSet rs = ps.executeQuery();
while (rs.next()) {
int id = rs.getInt(1);
// Some other actions
}
Me pregunté (y también a los autores del código) por qué no usar etiquetas para recuperar valores de columna:
int id = rs.getInt("CUSTOMER_ID");
La mejor explicación que he escuchado es sobre el rendimiento. Pero en realidad, ¿hace que el procesamiento sea extremadamente rápido? No lo creo, aunque nunca he realizado mediciones. Incluso si recuperar por etiqueta sería un poco más lento, sin embargo, proporciona una mejor legibilidad y flexibilidad, en mi opinión.
Entonces, ¿podría alguien darme una buena explicación para evitar recuperar valores de columna por índice de columna en lugar de columna? ¿Cuáles son los pros y los contras de ambos enfoques (tal vez, con respecto a cierto DBMS)?
Además de buscar en el mapa para las etiquetas, también genera una creación de Cadena adicional. Aunque ocurrirá en la pila, pero aún así tiene un costo.
Todo depende de la elección individual y hasta la fecha he usado solo índices :-)
Advertencia: voy a ser bombástico aquí, porque esto me vuelve loco.
El 99% * de las veces, es una micro-optimización ridícula que la gente tenga una idea vaga que hace las cosas "mejores". Esto ignora por completo el hecho de que, a menos que se encuentre en un círculo extremadamente cerrado y ocupado sobre millones de resultados de SQL todo el tiempo , lo cual es algo excepcional, nunca lo notará. Para todos los que no están haciendo eso, el costo de tiempo del desarrollador para mantener, actualizar y corregir errores en la indexación de columnas es mucho mayor que el costo incremental del hardware para su aplicación de rendimiento infinitamente peor.
No codifique optimizaciones como esta en. Código para la persona que lo mantiene. Luego observe, mida, analice y optimice. Observe nuevamente, mida nuevamente, analice nuevamente y optimice de nuevo.
La optimización es prácticamente el último paso en el desarrollo, no el primero.
* La figura está hecha.
Claro, usar nombres de columna aumenta la legibilidad y facilita el mantenimiento. Pero usar los nombres de las columnas tiene una contracara. Como sabe, SQL permite múltiples nombres de columna con el mismo nombre, no hay garantía de que el nombre de la columna que escribió en el método getter de resultSet realmente apunte al nombre de la columna a la que desea acceder. En teoría, se prefiere el uso de números de índice en lugar de nombres de columna, pero reduce la legibilidad ...
Gracias
De la documentación de java:
La interfaz ResultSet proporciona métodos getter (getBoolean, getLong, etc.) para recuperar valores de columna de la fila actual. Los valores se pueden recuperar utilizando el número de índice de la columna o el nombre de la columna. En general, usar el índice de columna será más eficiente. Las columnas se numeran a partir de 1. Para una portabilidad máxima, las columnas del conjunto de resultados dentro de cada fila deben leerse en orden de izquierda a derecha, y cada columna debe leerse solo una vez.
Por supuesto, cada método (nombrado o indexado) tiene su lugar. Estoy de acuerdo en que las columnas con nombre deben ser las predeterminadas. Sin embargo, en casos donde se requiere una gran cantidad de bucles, y donde la declaración SELECT se define y mantiene en la misma sección de código (o clase), los índices deben estar bien; es aconsejable enumerar las columnas seleccionadas, no solo "SELECT * FROM ...", ya que cualquier cambio de tabla romperá el código.
Deberías usar etiquetas de cadena por defecto.
Pros:
- Independencia del orden de las columnas
- Mejor legibilidad / mantenibilidad
Contras:
- No tiene control sobre los nombres de las columnas (acceso a través de procedimientos almacenados)
¿Cual preferirías?
¿Ints?
int i = 1;
customerId = resultSet.getInt (i ++);
customerName = resultSet.getString (i ++);
customerAddress = resultSet.getString (i ++);
o cuerdas?
customerId = resultSet.getInt ("customer_id");
customerName = resultSet.getString ("customer_name");
customerAddress = resultSet.getString ("customer_address");
¿Y qué pasa si hay una nueva columna insertada en la posición 1? ¿Qué código prefieres? O si se cambia el orden de las columnas, ¿qué versión de código necesitaría cambiar?
Es por eso que deberías usar etiquetas de cadena por defecto.
El controlador JDBC se ocupa de la búsqueda de índice de la columna. Por lo tanto, si extrae los valores por nombre de columna cada vez que el controlador realiza una búsqueda (generalmente en el mapa hash), verifica el índice correspondiente para el nombre de la columna.
Estoy de acuerdo con las respuestas anteriores de que el rendimiento no es algo que nos obligue a seleccionar ninguno de los enfoques. Sería bueno considerar las siguientes cosas en su lugar:
- Lectura del código: para cada desarrollador que lea las etiquetas de su código tiene mucho más sentido que los índices.
- Mantenimiento: piense en la consulta SQL y la forma en que se mantiene. Lo que es más probable que suceda en su caso después de corregir / mejorar / refactorizar la consulta SQL: cambiar el orden de las columnas extraídas o cambiar los nombres de las columnas de resultados. Me parece que cambiar el orden de las columnas extraídas (como los resultados de agregar / eliminar nuevas columnas en el conjunto de resultados) tiene una mayor probabilidad de suceder.
- Encapsulación: a pesar de la forma que elija, intente aislar el código donde ejecuta la consulta SQL y el conjunto de resultados de análisis en el mismo componente y haga que este componente tenga en cuenta los nombres de las columnas y su asignación a los índices (si decidió usarlos) )
Hice algunos perfiles de rendimiento sobre este tema exacto en una base de datos Oracle. En nuestro código tenemos un ResultSet con numerosas columnas y una gran cantidad de filas. De los 20 segundos (!) Que tarda la solicitud en ejecutar el método oracle.jdbc.driver.ScrollableResultSet.findColumn (String name), lleva unos 4 segundos.
Obviamente, hay algo mal con el diseño general, pero usar índices en lugar de los nombres de las columnas probablemente tomaría esto en 4 segundos.
La respuesta ha sido aceptada, sin embargo, aquí hay información adicional y experiencia personal que aún no he visto.
Utilice nombres de columna (se prefieren las constantes y no los literales) en general y si es posible. Esto es más claro, más fácil de mantener y es menos probable que los cambios futuros rompan el código.
Sin embargo, hay un uso para los índices de columna. En algunos casos, estos son más rápidos, pero no lo suficiente como para anular las razones anteriores de los nombres *. Estos son muy valiosos cuando se desarrollan herramientas y métodos generales relacionados con ResultSet
s. Finalmente, puede ser necesario un índice porque la columna no tiene un nombre (como un agregado sin nombre) o hay nombres duplicados, por lo que no hay una manera fácil de hacer referencia a ambos.
* Tenga en cuenta que he escrito algunos controladores JDBC y busqué dentro de algunas fuentes abiertas e internamente estas usan índices de columnas para hacer referencia a las columnas de resultados. En todos los casos con los que he trabajado, el controlador interno primero asigna un nombre de columna a un índice. Por lo tanto, puede ver fácilmente que el nombre de la columna, en todos los casos, siempre tomaría más tiempo. Sin embargo, esto puede no ser cierto para todos los conductores.
No creo que el uso de las etiquetas afecte el rendimiento mucho. Pero hay otra razón para no usar String
s. O int
s, para el caso.
Considera usar constantes. El uso de una constante int
hace que el código sea más legible, pero también menos propenso a tener errores.
Además de ser más legible, la constante también evita que hagas errores tipográficos en los nombres de las etiquetas; el compilador arrojará un error si lo haces. Y cualquier IDE que valga la pena lo recogerá. Este no es el caso si usa String
o ints
.
Usar el índice es un intento de optimización.
El tiempo ahorrado por esto se desperdicia por el esfuerzo extra que le lleva al desarrollador buscar los datos necesarios para verificar si su código funcionará correctamente después de los cambios.
Creo que es nuestro instinto incorporado utilizar números en lugar de texto.