Pregunta

Cuando uso JDBC, a menudo encuentro construcciones como

ResultSet rs = ps.executeQuery();
while (rs.next()) {
    int id = rs.getInt(1);
    // Some other actions
}

Me pregunté a mí mismo (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 algo relacionado con el rendimiento. Pero en realidad, ¿hace que el procesamiento sea extremadamente rápido? No lo creo, aunque nunca he realizado mediciones. Incluso si la recuperación por etiqueta sería un poco más lenta, sin embargo, proporciona una mejor legibilidad y flexibilidad, en mi opinión.
Entonces, ¿podría alguien darme una buena explicación sobre cómo evitar recuperar los valores de las columnas por índice de columna en lugar de la etiqueta de la columna? ¿Cuáles son los pros y los contras de ambos enfoques (tal vez, con respecto a ciertos DBMS)?

¿Fue útil?

Solución

Debería usar etiquetas de cadena de forma predeterminada.

Pros:

  • Independencia del orden de las columnas
  • Mejor legibilidad / mantenibilidad

Cons:

  • No tiene control sobre los nombres de columna (acceso mediante procedimientos almacenados)

¿Cuál preferirías?

ints?

  

int i = 1;
   customerId = resultSet.getInt (i ++);
   customerName = resultSet.getString (i ++);
   customerAddress = resultSet.getString (i ++);

o cadenas?

  

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 preferirías? O si se cambia el orden de las columnas, ¿qué versión de código necesitaría cambiar?

Es por eso que debe usar etiquetas de cadena de forma predeterminada.

Otros consejos

Advertencia: me voy a poner rimbombante aquí, porque esto me vuelve loco.

El 99% * de las veces, es una ridícula micro optimización que las personas tienen una idea vaga que hace que las cosas sean "mejores". Esto ignora por completo el hecho de que, a menos que esté en un ciclo extremadamente apretado y ocupado sobre millones de resultados SQL todo el tiempo , lo que es de esperar que sea raro, 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 la columna 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 nuevamente.

La optimización es prácticamente el último paso en el desarrollo, no el primero.

* La figura está compuesta.

La respuesta ha sido aceptada, sin embargo, aquí hay información adicional y experiencia personal que aún no he visto.

Use nombres de columna (se prefieren constantes y no literales) en general y si es posible. Esto es más claro, es 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 para los nombres *. Estos son muy valiosos cuando se desarrollan herramientas y métodos generales relacionados con ResultSet s. Finalmente, se puede requerir un índice porque la columna no tiene un nombre (como un agregado sin nombre) o porque 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 he buscado dentro de algunos de código abierto uno e internamente usan índices de columna 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 esos casos, siempre tomaría más tiempo. Sin embargo, esto puede no ser cierto para todos los controladores.

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 están numeradas 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 deberían ser las predeterminadas. Sin embargo, en los casos en que se requiere una gran cantidad de bucles, y donde la instrucción SELECT se define y mantiene en la misma sección de código (o clase), los índices deberían estar bien; es recomendable enumerar las columnas que se seleccionan, no solo " SELECT * FROM ... " ;, ya que cualquier cambio de tabla romperá el código.

Claro, el uso de nombres de columna aumenta la lectura y facilita el mantenimiento. Pero el uso de nombres de columna tiene un lado negativo. Como sabe, SQL permite múltiples nombres de columna con el mismo nombre, no hay garantía de que el nombre de columna que escribió en el método getter de resultSet realmente apunte al nombre de columna al que desea acceder. En teoría, se prefiere usar números de índice en lugar de nombres de columna, pero reduce la legibilidad ...

Gracias

No creo que usar las etiquetas afecte mucho el rendimiento. Pero hay otra razón para no usar String s. O int s, para el caso.

Considere usar constantes. El uso de una constante int hace que el código sea más legible, pero también es menos probable que tenga errores.

Además de ser más legible, la constante también le impide hacer errores tipográficos en los nombres de las etiquetas: el compilador arrojará un error si lo hace. Y cualquier IDE que valga la pena lo recogerá. Este no es el caso si usa String so ints .

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 (!) La solicitud tarda en ejecutar el método oracle.jdbc.driver.ScrollableResultSet.findColumn (nombre de cadena) tarda unos 4 segundos.

Obviamente hay algo mal con el diseño general, pero el uso de índices en lugar de los nombres de columna probablemente tomaría estos 4 segundos de distancia.

¡Puedes tener lo mejor de ambos! La velocidad de usar índices con la facilidad de mantenimiento y seguridad de usar nombres de columna.

Primero, a menos que esté haciendo un bucle a través de un conjunto de resultados, solo use nombres de columna.

  1. 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: p. iLast_Name.

  2. Antes de que el bucle del conjunto de resultados repita los metadatos de la columna y establezca el valor de cada variable entera en el índice de la columna del nombre de la columna correspondiente. Si el índice de la columna 'Apellido' es 3, establezca el valor de 'iLast_Name' en 3.

  3. En el bucle del 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 sobre el 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 del índice) solo se realiza una vez antes del ciclo en lugar de para cada registro y columna en el ciclo.

El controlador JDBC se encarga de que la columna indexe la búsqueda. Entonces, si extrae valores por nombre de columna cada vez que el controlador realiza una búsqueda (generalmente en un mapa hash) para verificar el índice correspondiente para el nombre de la columna.

Estoy de acuerdo con las respuestas anteriores en que el rendimiento no es algo que pueda obligarnos a seleccionar ninguno de los enfoques. Sería bueno considerar las siguientes cosas en su lugar:

  • Legibilidad de código: para cada desarrollador que lea las etiquetas de su código tienen mucho más sentido que los índices.
  • Mantenimiento: piense en la consulta SQL y la forma en que se mantiene. Qué 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 resultado de agregar / eliminar nuevas columnas en el conjunto de resultados) tiene una mayor probabilidad de suceder.
  • Encapsulación: a pesar de la forma en que elija, intente aislar el código donde ejecuta la consulta SQL y analice el conjunto de resultados en el mismo componente y haga que solo este componente conozca los nombres de columna y su asignación a los índices (si decidió para usarlos).

Usar el índice es un intento de optimización.

El tiempo ahorrado por esto se desperdicia por el esfuerzo adicional 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 usar números en lugar de texto.

Además de buscar etiquetas en el Mapa, también conduce a una creación de Cadena adicional. Aunque sucederá en la pila, aún conlleva un costo.

Todo depende de la elección individual y hasta la fecha, solo he usado índices :-)

Como lo señalan otros carteles, me apegaría a los nombres de columna a menos que tenga una razón realmente poderosa para no hacerlo. El impacto en el rendimiento es insignificante en comparación con, por ejemplo, la optimización de consultas. En este caso, el mantenimiento es mucho más importante que una pequeña optimización.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top