querysingle .net sqldatareader dapper

.net - querysingle - ¿Qué hace el parámetro almacenado en Dapper dot net?



dapper select object (3)

pero por lo que puedo decir, lo único que hace es enviar el resultado a una lista antes de devolverlo

No te estás perdiendo nada. Esa es la diferencia clave. Excepto que no es un elenco como tal: el objeto real devuelto es muy diferente. Básicamente, hay dos formas de leer datos:

  • en una API de transmisión, cada elemento se entrega individualmente; esto es muy eficiente en cuanto a la memoria, pero si haces un montón de procesamiento posterior por artículo, significa que tu conexión / comando podría estar "activo" por un tiempo prolongado
  • en una API protegida, todas las filas se leen antes de que se produzca nada

Si está leyendo una gran cantidad de datos (miles a millones de filas), una API no amortiguada puede ser preferible. De lo contrario, se usa mucha memoria y puede haber una latencia notable incluso antes de que esté disponible la primera fila. Sin embargo, en la mayoría de los escenarios comunes, la cantidad de datos leídos se encuentra dentro de los límites razonables, por lo que es razonable insertarlos en una lista antes de entregárselos a la persona que llama. Eso significa que el comando / lector, etc., se ha completado antes de que regrese.

Como nota al margen, el modo de búfer también evita el tan común "ya hay un lector abierto en la conexión" (o lo que sea que el fraseo sea exacto).

Dapper dot net tiene un parámetro de buffer (un bool), pero hasta donde puedo decir, lo único que hace es enviar el resultado a una lista antes de devolverlo.

Según la documentation :

El comportamiento predeterminado de Dapper es ejecutar su sql y almacenar en búfer todo el lector a su regreso. Esto es ideal en la mayoría de los casos, ya que minimiza bloqueos compartidos en el DB y reduce el tiempo de red db.

Sin embargo, al ejecutar grandes consultas, puede que necesite minimizar la huella de memoria y solo cargar objetos según sea necesario. Para hacerlo, pase, almacenado en búfer: falso en el método de consulta.

No estoy seguro de cómo lanzar el resultado a una lista logra esto. ¿Me estoy perdiendo de algo? Mi única idea es que se supone que establece CommandBehavior para ExecuteReader en CommandBehavior.SequentialAccess (pero no lo hace).


En la práctica, es mejor nunca usar buffered: false .

He encontrado incluso la lectura de muchos millones de filas que es más rápido y más eficiente en cuanto a la memoria para usar los resultados almacenados en búfer que los no almacenados. Tal vez haya un punto de cruce si sus tablas tienen 500 columnas y está leyendo decenas de millones o cientos de millones de filas.

Si los conjuntos de resultados son más pequeños que muchos miles de millones de valores, no vale la pena utilizarlos como buffered: false por cualquier motivo.

Me impactó durante el análisis real que la lectura de gigabytes de datos del servidor Sql era más rápida (2-6 veces más rápida) y más eficiente en la memoria en el modo de almacenamiento intermedio estándar. El aumento del rendimiento incluso representa la operación más pequeña posible, al agregar un objeto a una matriz dispersa por índice a una matriz que no cambia de tamaño. El uso de una matriz dispersa multi-gigabyte que cambia de una copia sin tamponar a una sierra amortiguada mejora dos veces el tiempo de carga. Escribir en un diccionario con sierra tamponada la mejora de 6x en el tiempo de carga al insertar millones de registros (el diccionario utilizó la PK int de la tabla como clave, de modo que es básico para el cálculo de código hash).

Como con todo lo relacionado con el rendimiento, siempre debes analizar. Sin embargo, puedo decirle que con un alto nivel de certeza, siempre comience con el comportamiento predeterminado de Dapper.


Tengo que estar en desacuerdo con @ chris-marisic en esto ... Me encontré con varias excepciones de "Memoria data.ToList() " en esa línea exacta ( data.ToList() ) cuando data.ToList() buffer: true . No fue una consulta de "zillion rows X bazillion columns", solo un resultado SQL de 5-6k filas regulares con aproximadamente 30 columnas.

Realmente depende de tu configuración. Por ejemplo, si su SQL e IIS se ejecutan en la misma máquina física o no. Y cuánta memoria está instalada en el equipo IIS, y cuál es la configuración del archivo de página, etc. Si el servidor web tiene 2 GB o menos, considere establecer "buffer: false" para informes súper pesados.