2011-03-10 15 views
6

Estoy escribiendo una aplicación que lee toda la tabla, procesa y luego escribe los datos resultantes en otra tabla. Estoy usando la clase SqlBulkCopy (versión .net de "bcp in") que hace la inserción muy rápido. Pero no puedo encontrar ninguna forma eficiente de seleccionar datos en primer lugar. no hay .net equivalente de "bcp out", que me parece extraño.¿Cuál es la forma más rápida de seleccionar una tabla completa en SQL Server?

Actualmente estoy usando select * from table_name. Por prespectiva, se requieren 2.5 segundos para seleccionar 6.000 filas ... y solo 600ms para insertar a granel el mismo número de filas.

Espero que la selección de datos siempre sea más rápida que la inserción. ¿Cuál es la forma más rápida de seleccionar todas las filas & columnas de una tabla?


Las respuestas a qeustions:

  • Cronometré mi selección para tomar 2.5 segundos 2 maneras. Primero fue mientras ejecutaba mi aplicación y ejecutaba un rastreo sql. segundo estaba ejecutando la misma consulta en SSMS. Ambos retured sobre el mismo resultado.
  • Estoy leyendo datos usando SqlDataReader.
  • Ninguna otra aplicación está usando esta base de datos.
  • Mi procesamiento actual tarda menos de 1 segundo, por lo que el tiempo de lectura de 2+ segundos es relativamente grande. Pero sobre todo estoy preocupado (interesado) en el rendimiento al escalar esto hasta 100.000 filas y millones de filas.
  • Sql Server 08r2 y mi aplicación se ejecutan en mi máquina de desarrollo.
  • Parte del procesamiento de datos se establece por lo que necesito tener toda la tabla en memoria (para admitir conjuntos de datos mucho más grandes, sé que este paso probablemente deba trasladarse a SQL, así que solo necesito operar por fila en memoria)

Aquí está mi código:

DataTable staging = new DataTable(); 
using (SqlConnection dwConn = (SqlConnection)SqlConnectionManager.Instance.GetDefaultConnection()) 
{ 
    dwConn.Open(); 
    SqlCommand cmd = dwConn.CreateCommand(); 
    cmd.CommandText = "select * from staging_table"; 

    SqlDataReader reader = cmd.ExecuteReader(); 
    staging.Load(reader); 
} 
+0

¿Cuánto tiempo tarda su procesamiento? – Andrey

+3

¿Cómo estás midiendo estos 2.5 segundos? ¿En SSMS o en tu aplicación? Si lo anterior, ¿qué sucede si activa la opción "Descartar resultados después de la ejecución" para eliminar el tiempo de procesamiento de SSMS? Si este último ¿Cómo recupera la aplicación las filas? ¿Está utilizando un lector de datos, por ejemplo? ¿Cómo se ve tu código? –

+1

Mientras está leyendo en esta tabla, ¿otras aplicaciones escriben en la tabla? Si es así, puede intentar usar la opción "CON (NOLOCK)". – WiseGuyEh

Respuesta

11

select * from table_namees la manera más simple, más fácil y más rápida de leer una tabla entera.

Déjame explicarte por qué tus resultados conducen a conclusiones erróneas.

  1. Copiar una tabla entera es una operación optimizada que requiere simplemente clonación los viejos datos binarios en la nueva (como máximo se puede realizar una operación de copia de archivos, de acuerdo con mecanismo de almacenamiento).
  2. La escritura está en el búfer. DBMS dice que el registro fue escrito, pero en realidad aún no está hecho, a menos que trabaje con transacciones. Las operaciones de disco generalmente se retrasan.
  3. Consultar una tabla también requiere (a diferencia de la clonación) adaptar los datos del diseño/formato almacenado en formato binario a un formato dependiente del controlador que finalmente es legible por su cliente. Esto lleva tiempo.
1

En general, es una buena idea incluir los nombres de columna en la lista de selección, pero con los RDBMS de hoy, no hará mucha diferencia. Solo verá diferencias en este sentido si limita las columnas seleccionadas. En general, es una buena práctica incluir nombres de columna.Pero para responder, parece que seleccionar es más lento que insertar en el escenario que describe y sí, select * from table_name es la forma más rápida de leer todas las filas y columnas de una tabla

+0

+1 porque esto * ES * útil e incluye un buen punto que estoy de acuerdo con que no está en la otra respuesta. –

2

Todo depende de su hardware, pero es es probable que su red sea el cuello de botella aquí.

Además de limitar su consulta a simplemente leer las columnas que en realidad estaría utilizando, hacer una selección es lo más rápido posible. Aquí está el almacenamiento en caché, cuando lo ejecuta dos veces seguidas, la segunda vez debe ser mucho más rápido porque los datos están en caché en la memoria. Ejecute dbcc dropcleanbuffers para verificar el efecto del almacenamiento en caché.

Si desea hacerlo lo más rápido posible intente implementar el código que procesa en T-SQL, de esa manera podría operar directamente sobre los datos allí en el servidor.

Otro buen consejo para la optimización de la velocidad es tener la tabla que se lee en un disco (observe los grupos de archivos) y la tabla que se escribe en otro disco. De esta forma, un disco puede hacer una lectura continua y el otro una escritura continua. Si ambas operaciones ocurren en el mismo disco, las cabezas del disco van y vienen, lo que reduce seriamente el rendimiento.

Si la escritura no se puede escribir en T-SQL, también podría echarle un vistazo a SQL CLR.

Otro consejo: cuando selecciona * de la tabla, use un lector de datos si es posible. De esta forma, no materializas todo en la memoria primero.

GJ

Cuestiones relacionadas