ResultSet: Recuperar valores de columna por índice versus recuperar por etiqueta


Cuando uso JDBC, a menudo me encuentro con construcciones 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 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 de evitar recuperar los valores de columna por índice de columna en lugar de etiqueta de columna? ¿Cuáles son los pros y los contras de ambos enfoques (tal vez, en relación con ciertos SGBD)?

Author: pyb, 2008-10-09

12 answers

Debe usar etiquetas de cadena por defecto.

Ventajas:

  • 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)

¿Cuál prefieres?

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 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 en todo?

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

 39
Author: Martin Klinke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-25 07:22:33

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

El 99%* del tiempo, es una microoptimización ridícula que la gente tenga una idea vaga que hace las cosas "mejores". Esto ignora completamente el hecho de que, a menos que esté en un bucle extremadamente apretado y ocupado sobre millones de resultados SQL todo el tiempo, lo cual es raro, nunca lo notará. Para todos los que no están haciendo eso, el costo de tiempo del desarrollador de mantener, actualizar y corregir errores en el la indexación de columnas es mucho mayor que el costo incremental del hardware para su aplicación infinitesimalmente peor rendimiento.

No codifique optimizaciones como esta. Código para la persona que lo mantiene. Luego observe, mida, analice y optimice. Observe de nuevo, mida de nuevo, analice de nuevo y optimice de nuevo.

La optimización es más o menos el último paso en el desarrollo, no el primero.

* La figura está hecha.

 51
Author: Cowan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-09 11:26:27

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

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.

Hay, sin embargo, un uso para índices de columna. En algunos casos, estos son más rápidos, pero no lo suficiente como para que esto anule lo anterior motivos de los nombres*. Estos son muy valiosos cuando se desarrollan herramientas y métodos generales que tratan con ResultSet s. Finalmente, un índice puede ser necesario 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 miré dentro de algunos open sources uno e internamente estos utilizan índices de columna para hacer referencia a las columnas de resultados. En todos los casos con los que he trabajado, el el controlador 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 llevaría más tiempo. Sin embargo, esto puede no ser cierto para todos los conductores.

 6
Author: Kevin Brock,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-04 05:10:51

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 desde 1. Para una máxima portabilidad, las columnas del conjunto de resultados dentro de cada fila deben leerse en orden de izquierda a derecha, y cada columna debe ser lea 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 el valor predeterminado. Sin embargo, en los casos en los que se requiere un gran número de bucles, y donde la instrucció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 que se seleccionan, no solo "SELECT * FROM"...", ya que cualquier cambio de tabla romperá el código.

 5
Author: Jason,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-26 06:27:26

Claro, el uso de nombres de columna aumenta la readibilidad y facilita el mantenimiento. Pero usar nombres de columna tiene un lado opuesto. 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 el uso de números de índice en lugar de nombres de columna, pero reduce la legibilidad...

Gracias

 4
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-04 04:57:55

No creo que el uso de las etiquetas impacte mucho en el rendimiento. Pero hay otra razón para no usar Strings. 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 menos probable que tenga 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 lanzará un error si lo haces. Y cualquier IDE que valga algo lo recogerá. Este no es el caso si utilizar String s o ints.

 2
Author: Sietse,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-09 11:27:11

Hice algunos perfiles de rendimiento sobre este tema exacto en una base de datos Oracle. En nuestro código tenemos un conjunto de resultados con numerosas columnas y un gran número de filas. De los 20 segundos (!) la solicitud toma para ejecutar el método oracle.jdbc.controlador.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 esto 4 segundos de distancia.

 2
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-31 09:06:00

Usted puede 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é 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: por ejemplo, iLast_Name.

  2. Antes del bucle de conjunto de resultados, itere a través de los metadatos de la columna y establezca el valor de cada entero variable al índice de columna del nombre de columna correspondiente. Si el índice de la columna 'Last_Name' es 3, establezca el valor de 'iLast_Name' en 3.

  3. En el bucle result set use los nombres de 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 dará el mejor rendimiento.

NOTA: la asignación inicial (es decir, el nombre de la columna al índice la asignación) solo se realiza una vez antes del bucle en lugar de para cada registro y columna en el bucle.

 2
Author: Rick Post,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-28 21:00:09

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

 1
Author: zloster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-09 11:24:20

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

  • Legibilidad del código: para cada desarrollador que lea sus etiquetas de código tienen mucho más sentido que los índices.
  • Maintenance: 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 arreglar/mejorar / refactorizar la consulta SQL: cambiar el orden de las columnas nombres de columna de resultados extraídos o cambiantes. 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 analizar el conjunto de resultados en el mismo componente y hacer que solo este componente conozca los nombres de las columnas y su asignación a los índices (si decide usarlos).
 0
Author: Cha2lenger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-09 12:20:59

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

El tiempo ahorrado por esto se pierde por el esfuerzo adicional que toma el desarrollador para buscar los datos necesarios para comprobar si su código funcionará correctamente después de los cambios.

Creo que es nuestro instinto incorporado usar números en lugar de texto.

 0
Author: databyss,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-09 12:29:17

Además de buscar etiquetas en el mapa, también conduce a una creación de cadenas extra. Aunque pasará en la pila, pero todavía caries un costo con ella.

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

 0
Author: Vinod Singh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-19 09:20:11