2009-07-10 27 views
17

Estoy usando VSTS 2008 + C# + .Net 3.5 + SQL Server 2008 + ADO.Net. Si cargué una tabla de una base de datos usando un DataTable de ADO.Net, y en la tabla de la base de datos, definí un par de índices en la tabla. Mi pregunta es si, en ADO.Net DataTable, hay un índice relacionado (el mismo que los índices que creé en la tabla de la base de datos física) para mejorar el rendimiento de ciertas operaciones en DataTable.¿Las tablas de datos ADO.Net tienen índices?

gracias de antemano, George

+1

[Tenga en cuenta que DataViews * do * tiene índices] (https://msdn.microsoft.com/en-us/library/bb669089 (v = vs.110) .aspx). "El índice para un DataView está construido tanto cuando se crea el DataView como cuando se modifica cualquiera de los datos de clasificación o filtrado". –

Respuesta

0

George,

La respuesta es no.

En realidad, se puede usar algún tipo de indexación internamente, pero solo como un detalle de implementación. Por ejemplo, si crea una restricción de clave externa, tal vez eso sea ayudado por un índice. Pero no le importa a un desarrollador.

+0

Estoy confundido. 1. ¿Podemos usar/crear un índice en DataTable para mejorar el rendimiento? 2. Si DataTable no usa el índice, ¿cómo podría mejorar el rendimiento? – George2

+1

George, ¿por qué en el mundo crees que tienes que mejorar el rendimiento? –

+0

Hola John, creo que DataTable es un mapeo (de memoria) o equivalente de una tabla de base de datos física, y dado que necesitamos índice en la tabla de base de datos física para mejorar el rendimiento, ¿por qué no tenemos el concepto de índice en DataTable? ¿Significa que el índice no mejora el rendimiento de DataTable? – George2

4

John anterior es correcto. Los DataTables están desconectados en estructuras de memoria. No se asignan a la implementación física de la base de datos.

Los índices en el disco se utilizan para acelerar las búsquedas porque no tiene todas las filas. Si tiene que cargar cada fila y escanearlas, es lenta, por lo que un índice tiene sentido. En una DataTable ya tiene todas las filas, por lo que una comparación ya es rápida.

2

Otros han señalado que un DataSet no está destinado a servir como un sistema de base de datos, solo una representación de datos. Si está trabajando con la impresión de que un DataSet es una base de datos, se equivoca y es posible que deba reconsiderar su implementación.

Si necesita una base de datos del lado del cliente, considere usar SQL Compact o SQL Lite, ambos son sistemas de base de datos redistribuibles gratuitos que pueden utilizarse sin requerir instalaciones o servicios por separado. Si necesita algo más completo, SQL Express es el siguiente paso.

Sin embargo, para ayudar a aclarar, los DataSets/Tables se usan en el desarrollo de .NET para contener datos temporalmente según sea necesario. Piense en ellos como los resultados de una consulta SELECT contra una base de datos; son más o menos similares a los archivos CSV u otras formas de datos tabulares: puede extraer datos de una base de datos, trabajar con los datos y luego volver a enviar los cambios a una base de datos, pero ellos, por sí mismos, no bases de datos.

Si tiene una gran colección de elementos que necesita conservar en la memoria por una razón u otra, entonces podría considerar construir un DTO liviano (objeto de transferencia de datos, Google it, son muy simples) y cargarlos en un HashTable. HashTables no le dará ningún tipo de datos relacionales, pero son muy eficientes en las búsquedas.

+0

Gracias John y Yoooder, estoy pensando en por qué estoy confundido antes.Creo que incluso si los valores iniciales de DataTable se recuperan de un SELECT de la base de datos normalmente, pero podemos emitir seleccionar en DataTable para obtener un subconjunto de datos de DataTable, y es por eso que estoy confundido antes y es por eso que pienso cuando emitir SELECT en DataTable, tal vez necesito crear un índice para facilitar el rendimiento de la consulta, ¿algún comentario? – George2

1

Las tablas de datos tienen un campo PrimaryKey que puede servir como índice (ya son rápidas). Este campo no se copia de las claves principales de la base de datos (aunque eso podría ser bueno).

+0

¿Lo has probado? – chikak

18

En realidad, la pregunta de George no es tan "mala" como algunas personas insisten que es. (Estoy cada vez más convencido de que no hay tal cosa como "una mala pregunta".)

Tengo una mesa bastante grande que cargo en la memoria, en un objeto DataTable. Se realiza mucho procesamiento en líneas de esta tabla, muchas veces, en varios subconjuntos (y diferentes) que puedo describir fácilmente como "DONDE ..." de las cláusulas SELECT. Ahora con esta DataTable puedo ejecutar Select() - un método de clase DataTable - pero es bastante ineficiente.

Al final, decidí cargar el DataTable ordenado por columnas específicas e implementé mi propia búsqueda rápida , en lugar de usar la función Seleccionar(). Resultó ser mucho más rápido, pero por supuesto solo funciona en esas columnas ordenadas. El problema se habría evitado si DataTable tuviera índices.

+0

Pero hay muy pocos desarrolladores que tienen el problema que describes. Sería una pérdida de tiempo para Microsoft implementar "índices" en la clase DataTable solo para usted. –

+2

@JohnSaunders Cargar una DataTable en la memoria para utilizarla en un gran número de búsquedas no parece ser algo que "muy pocos desarrolladores" tendrían que hacer. Dada la variedad de aplicaciones basadas en bases de datos, parece una cosa bastante común de hacer. Es por eso que Microsoft implementó [DataViews que sí crean índices] (https://msdn.microsoft.com/en-us/library/bb669089 (v = vs.110) .aspx). –

+0

@bacon, no importa si crees que "muy pocos desarrolladores" deben hacerlo. Son hechos que importan. Y las aplicaciones basadas en bases de datos usan bases de datos, no en objetos DataTable de memoria. Además, tenga en cuenta que el OP simplemente se confundió como un novato y se confundió sobre el papel de una DataTable. –

7

Se puede crear una clave principal de la tabla de datos. Las operaciones de filtro obtienen un gran impulso si está buscando en el campo de la clave principal. Echa un vistazo a este enlace: here

4

Tuve el mismo problema con muchas consultas de una tabla de datos grande que no están de acuerdo con la clave principal.

La solución que encontré fue crear DataView para cada índice que quería usar, y luego usar sus métodos Find y FindRows para extraer los datos.

DataView crea un índice interno en la DataTable y se comporta prácticamente como un índice para este fin.

En mi caso, yo era capaz de reducir 10.000 consultas desde 40 segundos a un !!!

0

Mi lectura de los documentos es que la forma correcta de lograr esto (si es necesario) es utilizar AsDataView para producir un DataView (o LinqDataView) que está destinado a la tabla subyacente. Si su DataTable es invariable, entonces el DataView puede ser estático para evitar una nueva indexación redundante.

Actualmente estoy investigando Linq to DataSet, y esta q fue útil para mí, así que gracias.

1

Las tablas de datos se indexan si usted (el codificador) especifica una o más DataColumns como clave principal. Interalmente, ADO.NET utiliza un árbol Rojo-Negro para formar este índice que brinda búsquedas de tiempo de registro. Esta clave principal no se establece automáticamente en función de cualquier clave subyacente del proveedor de datos.

+0

DataTables no tienen proveedor de datos. –

8

No, pero posiblemente sí.

Puede configurar sus propios índices en una DataTable, utilizando un DataView. A medida que cambie la tabla, se reconstruirá DataView, por lo que el índice siempre debe estar actualizado.

Hice algunas pruebas en banco para mi propia aplicación. Uso una DataTable para aproximar un Boost MultiIndexContainer. Para crear un índice en una columna llamada "autor", que inicializar el DataTable, y luego el DataView ...

_dvChangesByAuthor = 
    new DataView(
     _dtChanges, 
     string.Empty, 
     "Author ASC", 
     DataViewRowState.CurrentRows); 

a continuación, extraer datos por autor de la mesa, se utiliza la función de la vista FindRows ...

  dataRowViews = _dvChangesByAuthor.FindRows(author); 
      List<DataRow> returnRows = new List<DataRow>(); 
      foreach (DataRowView drv in dataRowViews) 
      { 
       returnRows.Add(drv.Row); 
      } 

I hizo una gran DataTable al azar, y corrieron consultas utilizando DataTable.Select(), Linq-To-conjunto de datos (con la ejecución forzada mediante la exportación a la lista) y el método DataView anteriormente. El método DataView ganó fácilmente. LINQ tomó garrapatas 5000, Select tomó más de 26.000 garrapatas, DataView tomó 192 garrapatas ...

LOC=20141121-14:46:32.863,UTC=20141121-14:46:32.863,DELTA=72718,THR=9,DEBUG,LOG=Program,volumeTest() - Running queries for author >TFYN_AUTHOR_047< 
LOC=20141121-14:46:32.863,UTC=20141121-14:46:32.863,DELTA=72718,THR=9,DEBUG,LOG=RightsChangeTracker,GetChangesByAuthorUsingLinqToDataset() - Query elapsed time: 2 ms, 4934 ticks; Rows=65 
LOC=20141121-14:46:32.879,UTC=20141121-14:46:32.879,DELTA=72733,THR=9,DEBUG,LOG=RightsChangeTracker,GetChangesByAuthorUsingSelect() - Query elapsed time: 11 ms, 26575 ticks; Rows=65 
LOC=20141121-14:46:32.879,UTC=20141121-14:46:32.879,DELTA=72733,THR=9,DEBUG,LOG=RightsChangeTracker,GetChangesByAuthorUsingDataview() - Query elapsed time: 0 ms, 192 ticks; Rows=65 

Por lo tanto, si desea índices en un DataTable, sugeriría DataView, si se puede tratar con el hecho de que el índice se reconstruye cuando los datos cambian.

1

La respuesta correcta aquí es crear un DataView de la DataTable, que según the doc creará un índice:

DataView construye un índice. Un índice contiene claves creadas a partir de una o más columnas en la tabla o vista. Estas claves se almacenan en una estructura que permite que DataView encuentre la fila o las filas asociadas con los valores clave de forma rápida y eficiente. Las operaciones que usan el índice, como el filtrado y la clasificación, aumentan significativamente el rendimiento. El índice para un DataView se crea tanto cuando se crea el DataView como cuando se modifica cualquiera de los datos de clasificación o filtrado. Crear un DataView y luego establecer la información de clasificación o filtrado más tarde hace que el índice se construya al menos dos veces: una vez cuando se crea DataView, y nuevamente cuando se modifica cualquiera de las propiedades de clasificación o filtro.

Cuestiones relacionadas