Después de leer el siguiente artículo, descubrí que la prueba del autor es realmente útil para los amigos que usan ASP. Debería ser similar no solo para ASP sino también para otros lenguajes. Generar contenido dinámico en el servidor es una de las razones principales para usar ASP, por lo que el primer proyecto de prueba que elegimos fue determinar el mejor método para enviar contenido dinámico al flujo de respuesta. Hay dos opciones básicas (y algunas variaciones de ellas): usar etiquetas ASP en línea y usar la declaración Response.Write.
Para probar estos diferentes enfoques, creamos una página ASP simple que definió algunas variables y luego las insertó en una tabla. Aunque esta página es simple y no tiene utilidad práctica, es suficiente para permitirnos aislar y probar problemas individuales.
2.1 Uso de etiquetas en línea ASP
La primera prueba es utilizar la etiqueta en línea de ASP <%= x %>, donde x es una variable. Este es el método más conveniente de usar y hace que la parte HTML de la página sea más fácil de leer y mantener.
Copie el código de código de la siguiente manera:
<% OPCIÓN EXPLÍCITA
Nombre tenue
DimApellido
Dim MiddleInicial
Dirección tenue
Ciudad oscura
Estado oscuro
Número de teléfono tenue
Número de fax oscuro
Correo electrónico oscuro
fecha de nacimiento tenue
Nombre = Juan
Inicial Medio = Q
Apellido = Público
Dirección = 100 calle principal
Ciudad=Nueva York
Estado = Nueva York
Número de teléfono = 1-212-555-1234
Número de fax = 1-212-555-1234
Correo electrónico = [email protected]
Fecha de nacimiento = 1/1/1950
%>
<HTML>
<CABEZA>
<TITLE>Prueba de respuesta</TITLE>
</CABEZA>
<CUERPO>
<H1>Prueba de respuesta</H1>
<TABLA>
<tr><td><b>Nombre:</b></td><td><%= Nombre %></td></tr>
<tr><td><b>Inicial del segundo nombre:</b></td><td><%= Inicial del segundo nombre %></td></tr>
<tr><td><b>Apellido:</b></td><td><%= Apellido %></td></tr>
<tr><td><b>Dirección:</b></td><td><%= Dirección %></td></tr>
<tr><td><b>Ciudad:</b></td><td><%= Ciudad %></td></tr>
<tr><td><b>Estado:</b></td><td><%= Estado %></td></tr>
<tr><td><b>Número de teléfono:</b></td><td><%= Número de teléfono %></td></tr>
<tr><td><b>Número de fax:</b></td><td><%= Número de fax %></td></tr>
<tr><td><b>Correo electrónico:</b></td><td><%= Correo electrónico %></td></tr>
<tr><td><b>Fecha de nacimiento:</b></td><td><%= Fecha de nacimiento %></td></tr>
</TABLA>
</CUERPO>
</HTML>
El código completo de /app1/response1.asp
Mejor registro = 8,28 ms/página
2.2 Utilice Response.Write para generar cada línea de código HTML
Existe mucha buena literatura que afirma que se debe evitar el enfoque de marcado en línea anterior porque da como resultado una operación llamada cambio de contexto. Esta operación ocurre cuando el tipo de código procesado por el servidor web cambia (de enviar HTML puro a procesamiento de script, o viceversa), y este cambio lleva una cierta cantidad de tiempo. Después de que muchos programadores aprenden esto, su primera reacción es usar la función Response.Write para generar cada línea de código HTML:
Copie el código de código de la siguiente manera:
...
Respuesta.Escribir(<html>)
Respuesta.Escribir(<cabeza>)
Response.Write( <título>Prueba de respuesta</título>)
Respuesta.Escribir(</head>)
Respuesta.Escribir(<cuerpo>)
Response.Write(<h1>Prueba de respuesta</h1>)
Respuesta.Escribir(<tabla>)
Response.Write(<tr><td><b>Nombre:</b></td><td> & Nombre & </td></tr>)
Response.Write(<tr><td><b>Inicial del segundo nombre:</b></td><td> & Inicial del segundo nombre & </td></tr>)
...
Fragmento /app1/response2.asp
Mejor registro = 8,28 ms/página
Tiempo de respuesta = 8,08 ms/página
Diferencia = -0,20 ms (reducción del 2,4%)
La mejora de rendimiento que vimos en comparación con la versión de marcado en línea fue tan pequeña que fue simplemente sorprendente. Esto puede deberse a que hay muchas más llamadas a funciones en la página. Sin embargo, este método tiene una desventaja mayor, dado que el código HTML está incrustado en la función, el código del script se vuelve muy largo e incómodo de leer y mantener.
2.3 Usar funciones contenedoras
Response.Write no agrega CRLF (Retorno de carro - Avance de línea, Retorno de carro - Avance de línea) al final de la línea de texto, que es el aspecto más decepcionante del uso del método anterior. Aunque el código HTML ha sido bien formateado en el lado del servidor, lo que ve en el navegador sigue siendo sólo una larga línea de código. Pero este problema no fue la única decepción. La gente pronto descubrió que no existía una función Response.WriteLn que pudiera agregar CRLF automáticamente. Una reacción natural es crear una función contenedora para Response.Write y agregue CRLF después de cada línea:
...
writeCR(<tr><td><b>Nombre:</b></td><td> & Nombre & </td></tr>)
...
SUB escribirCR(cadena)
Respuesta.Escribir(cadena y vbCRLF)
FINAL SUB
Fragmento /app1/response4.asp
Mejor registro = 8,08 ms/página
Tiempo de respuesta = 10,11 ms/página
Diferencia = +2,03 ms (aumento del 25,1%)
El resultado es una disminución significativa del rendimiento. Por supuesto, esto se debe principalmente a que este método duplica el número de llamadas a funciones y su impacto en el rendimiento es muy obvio. Este uso debe evitarse a toda costa, CRLF genera dos bytes adicionales al final de cada línea y estos dos bytes son inútiles para que el navegador muestre la página. En la mayoría de los casos, el hermoso formato del código HTML del navegador facilita que sus competidores lean y comprendan el diseño de la página.
2.4 Fusionar múltiples respuestas. Escribir
Ignorando la última prueba sobre encapsulación de funciones, el siguiente paso lógico sería fusionar todas las cadenas de declaraciones Response.Write separadas en una sola declaración, reduciendo así la cantidad de llamadas a funciones y mejorando la eficiencia del código.
Copie el código de código de la siguiente manera:
Respuesta.Escribir(<html> & _
<cabeza> & _
<title>Prueba de respuesta</title> & _
</cabeza> & _
<cuerpo> & _
<h1>Prueba de respuesta</h1> & _
<tabla> & _
<tr><td><b>Nombre:</b></td><td> & Nombre & </td></tr> & _
...
<tr><td><b>Fecha de nacimiento:</b></td><td> & Fecha de nacimiento & </td></tr> & _
</tabla> & _
</cuerpo> & _
</html>)
Fragmento /app1/response3.asp
Mejor registro = 8,08 ms/página
Tiempo de respuesta = 7,05 ms/página
Diferencia = -1,03 ms (reducción del 12,7%)
Este es, con diferencia, el mejor método.
2.5 Combine múltiples respuestas. Escriba y agregue CRLF al final de cada línea
Algunas personas también están muy preocupadas por si su código HTML se ve hermoso en el lado del navegador, por lo que agregamos un retorno de carro al final de cada línea de código HTML, usando la constante vbCRLF. Los demás códigos de prueba son los mismos que en el ejemplo anterior. .
...
Respuesta.Write(<html> & vbCRLF & _
<cabeza> & vbCRLF & _
<title>Prueba de respuesta</title> & vbCRLF & _
</head> & vbCRLF & _
...
Fragmento /app1/response5.asp
Mejor registro = 7,05 ms/página
Tiempo de respuesta = 7,63 ms/página
Diferencia = +0,58 ms (aumento del 8,5%)
El resultado es una ligera disminución en el rendimiento, probablemente debido a la adición de operaciones de concatenación de cadenas y al aumento del texto de salida.
2.6 Comentarios
Según los resultados de la prueba de salida ASP anterior, llegamos a las siguientes reglas de codificación:
Evite el uso excesivo de ASP integrado.
Combine tantas declaraciones Response.Write como sea posible en una sola declaración.
Nunca encapsule Response. Escriba solo para agregar CRLF.
Si desea formatear la salida HTML, agregue CRLF directamente después de la declaración Response.Write.
Esquema: ¿Cuál es la forma más eficiente de generar contenido generado dinámicamente por ASP? ¿Cuál es la mejor manera de extraer un conjunto de registros de base de datos? Este artículo prueba casi 20 problemas comunes en el desarrollo de ASP. El tiempo que muestra la herramienta de prueba nos dice: estos problemas que generalmente se dan por sentado no solo merecen atención, sino que también esconden secretos inesperados.
1. Propósito de la prueba
La primera parte de este artículo examina algunos problemas básicos en el desarrollo de ASP y brinda algunos resultados de pruebas de rendimiento para ayudar a los lectores a comprender qué impacto tiene el código colocado en la página en el rendimiento. ADO es una interfaz de base de datos universal y fácil de usar desarrollada por Microsoft. Resulta que interactuar con la base de datos a través de ADO es una de las aplicaciones más importantes de ASP. En la segunda parte, estudiaremos este tema.
La funcionalidad proporcionada por ADO es bastante extensa, por lo que la mayor dificultad al preparar este artículo es cómo definir el alcance del problema. Teniendo en cuenta que extraer grandes cantidades de datos puede aumentar significativamente la carga en el servidor web, decidimos que el objetivo principal de esta sección es descubrir cuál es la configuración óptima para operar conjuntos de registros ADO. Sin embargo, incluso después de reducir el alcance del problema, todavía nos enfrentamos a grandes dificultades, porque ADO puede tener muchas formas diferentes de completar la misma tarea. Por ejemplo, los conjuntos de registros se pueden extraer no solo a través de la clase Recordset, sino también a través de las clases Connection y Command, incluso después de obtener el objeto del conjunto de registros, existen muchos métodos de operación que pueden afectar drásticamente el rendimiento. Sin embargo, al igual que en la primera parte, intentaremos abarcar la gama más amplia posible de cuestiones.
Específicamente, el objetivo de esta sección es recopilar suficiente información para responder las siguientes preguntas:
¿Se debe hacer referencia a ADOVBS.inc mediante include?
l¿Debo crear un objeto de conexión independiente cuando uso conjuntos de registros?
l¿Cuál es la mejor manera de extraer un conjunto de registros?
l¿Qué tipo de cursor y método de bloqueo de registros son los más eficientes?
¿Debo utilizar un conjunto de registros local?
l¿Cuál es la mejor manera de configurar las propiedades del conjunto de registros?
l¿Qué método es más eficaz para hacer referencia a valores de campo en un conjunto de registros?
¿Es una buena forma de recopilar resultados con una cadena temporal?
2. Entorno de prueba
En esta prueba se utilizaron un total de 21 archivos ASP, que se pueden descargar desde la parte posterior de este artículo. Cada página está configurada para ejecutar tres consultas diferentes, devolviendo 0, 25 y 250 registros respectivamente. Esto nos ayudará a aislar la inicialización y la sobrecarga de ejecución de la página misma de la sobrecarga de recorrer el conjunto de registros.
Para facilitar las pruebas, la cadena de conexión de la base de datos y la cadena de comando SQL se guardan como variables de aplicación en Global.asa. Dado que nuestra base de datos de prueba es SQL Server 7.0, la cadena de conexión especifica OLEDB como proveedor de conexión y los datos de prueba provienen de la base de datos Northwind de SQL Server. El comando SQL SELECT extrae 7 campos especificados de la tabla de pedidos de NorthWind.
Copie el código de código de la siguiente manera:
<IDIOMA DE ESCRITURA=VBScript RUNAT=Servidor>
Subaplicación_OnStart
Aplicación (Conexión) = Proveedor = SQLOLEDB;
Servidor=MiServidor;
uid=sa;&_
contraseña=; & _
BASE DE DATOS=viento del norte
Aplicación (SQL) = SELECTTOP 0ID de pedido, & _
ID de cliente, & _
ID de empleado, & _
Fecha del pedido, & _
Fecha requerida, & _
Fecha de envío, & _
Transporte & _
DESDE[Pedidos]
Subtítulo final
</SCRIPT>
'sql alternativo - 25 registros
Aplicación (SQL) = SELECTTOP 25ID de pedido, & _
ID de cliente, & _
ID de empleado, & _
Fecha del pedido, & _
Fecha requerida, & _
Fecha de envío, & _
Transporte & _
DESDE[Pedidos]
'registros sql-250 alternativos
Aplicación (SQL) = SELECTTOP 250 ID de pedido, & _
ID de cliente, & _
ID de empleado, & _
Fecha del pedido, & _
Fecha requerida, & _
Fecha de envío, & _
Transporte & _
DESDE[Pedidos]
La configuración del servidor de prueba fue la siguiente: Pentium de 450 Mhz, 512 MB de RAM, NT Server 4.0 SP5, MDAC 2.1 (componente de acceso a datos) y Microsoft Scripting Engine versión 5.0. SQL Server se está ejecutando en otra máquina con una configuración similar. Como en la primera parte, todavía utilizamos la herramienta de estrés de aplicaciones web de Microsoft para registrar el tiempo desde la solicitud de la primera página hasta el último byte recibido del servidor (TTLB, tiempo hasta el último byte), el tiempo está en milisegundos. El script de prueba llamó a cada página más de 1300 veces y tardó aproximadamente 20 horas en ejecutarse. Los tiempos que se muestran a continuación son el TTLB promedio para la sesión. Recuerde, como en la primera parte, sólo nos preocupa la eficiencia del código, no su escalabilidad o el rendimiento del servidor.
También tenga en cuenta que hemos habilitado el almacenamiento en búfer del servidor. Además, para que todos los nombres de archivos tengan la misma longitud, algunos nombres de archivos tienen uno o más guiones bajos incrustados.
3. Primera prueba
En la primera prueba, extrajimos un conjunto de registros que simulaba un escenario típico que se encuentra en los ejemplos de Microsoft ASP ADO. En este ejemplo (ADO__01.asp), primero abrimos una conexión y luego creamos el objeto de conjunto de registros. Por supuesto, el script aquí está optimizado de acuerdo con las reglas de codificación resumidas en la primera parte de este artículo.
Copie el código de código de la siguiente manera:
<% Opción Explícita %>
<!-- #Incluir archivo=ADOVBS.INC -->
<%
ObjConn tenue
objRS tenue
Respuesta.Escribir(_
<HTML><CABEZAL> & _
<TITLE>Prueba ADO</TITLE> & _
</CABEZA><CUERPO> _
)
Establecer objConn = Server.CreateObject(ADODB.Connection)
objConn.Abrir aplicación (Conexión)
Establecer objRS = Server.CreateObject(ADODB.Recordset)
objRS.ActiveConnection = objConn
objRS.CursorType = adOpenForwardOnly
objRS.LockType = adLockReadOnly
objRS.Aplicación abierta (SQL)
Si objRS.EOF Entonces
Respuesta.Escribir (No se encontraron registros)
Demás
'escribir encabezados
Respuesta.Escribir(_
<BORDE DE LA TABLA=1> & _
<TR> & _
<TH>ID de pedido</TH> & _
<TH>ID de cliente</TH> & _
<TH>ID de empleado</TH> & _
<TH>Fecha del pedido</TH> & _
<TH>Fecha requerida</TH> & _
<TH>Fecha de envío</TH> & _
<TH>Flete</TH> & _
</TR> _
)
'escribir datos
Hacer mientras no objRS.EOF
Respuesta.Escribir(_
<TR> & _
<TD> & objRS(IDPedido) & </TD> & _
<TD> & objRS(ID de cliente) & </TD> & _
<TD> & objRS(ID de empleado) & </TD> & _
<TD> & objRS(FechaPedido) & </TD> & _
<TD> & objRS(FechaRequerida) & </TD> & _
<TD> & objRS(Fecha de envío) & </TD> & _
<TD> & objRS(Flete) & </TD> & _
</TR> _
)
objRS.MoveNext
Bucle
Respuesta.Escribir(</TABLE>)
Terminar si
objRS.Cerrar
objConn.Cerrar
Establecer objRS = Nada
Establecer objConn = Nada
Respuesta.Escribir(</BODY></HTML>)
%>
Aquí están los resultados de la prueba:
Echemos un vistazo al significado de los números en cada columna:
0 devuelve el TTLB (en milisegundos) requerido para una página de 0 registros. En todas las pruebas, este valor se considera el tiempo necesario para generar la página en sí (incluida la creación de objetos), excluyendo el tiempo de iteración a través de los datos del conjunto de registros.
25 TTLB en milisegundos para buscar y mostrar 25 registros
El TTLB en la columna de tiempo total/2525 se divide por 25, que es el costo de tiempo promedio total por registro.
tiempo de visualización/2525 columna TTLB menos 0 columna TTLB, luego divida por 25. Este valor refleja el tiempo necesario para mostrar un solo registro mientras se recorre el conjunto de registros.
250 Extrae y muestra TTLB de 250 registros.
El TTLB en la columna tiempo total/250250 se divide por 25. Este valor representa el costo de tiempo promedio total de un solo registro.
disp time/250 El TTLB en la columna 250 se resta del TTLB en la columna 0 y luego se divide por 250. Este valor refleja el tiempo necesario para mostrar un solo registro mientras se recorre el conjunto de registros.
Los resultados de las pruebas anteriores se utilizarán para compararlos con los resultados de las siguientes pruebas.
4. ¿Se debe hacer referencia a ADOVBS.inc mediante la inclusión?
ADOVBS.inc proporcionado por Microsoft contiene 270 líneas de código que definen la mayoría de las constantes de propiedad de ADO. Nuestro ejemplo solo hace referencia a 2 constantes de ADOVBS.inc. Por lo tanto, en esta prueba (ADO__02.asp) eliminamos la referencia del archivo incluido y utilizamos directamente el valor correspondiente al configurar las propiedades.
objRS.CursorType = 0?'
objRS.LockType = 1' adLockReadOnly
Puede ver que la sobrecarga de la página se redujo en un 23%. Este valor no afecta el tiempo de recuperación y visualización de registros individuales, ya que los cambios aquí no afectan las operaciones del conjunto de registros dentro del bucle. Hay varias formas de resolver problemas de referencia de ADOVBS.inc. Recomendamos utilizar el archivo ADOVBS.inc como referencia y explicar la configuración mediante comentarios. Recuerde, como se indicó en la Parte 1, el uso moderado de comentarios tiene un impacto mínimo en la eficiencia de su código. Otro método es copiar las constantes que necesita del archivo ADOVBS.inc a la página.
También hay una buena manera de resolver este problema, que es hacer que todas las constantes ADO estén disponibles directamente vinculándolas a la biblioteca de tipos ADO. Agregue el siguiente código al archivo Global.asa para acceder directamente a todas las constantes de ADO:
<!--TIPO DE METADATOS=typelib
FILE=C:Archivos de programaArchivos comunesSYSTEMADOmsado15.dll
NOMBRE=Biblioteca de tipos ADODB -->
o:
<!--TIPO DE METADATOS=typelib
UUID=00000205-0000-0010-8000-00AA006D2EA4
NOMBRE=Biblioteca de tipos ADODB -->
Por tanto, nuestra primera regla es:
Evite incluir el archivo ADOVBS.inc y acceda y utilice constantes ADO a través de otros métodos.
5. ¿Debo crear un objeto de conexión independiente cuando uso un conjunto de registros?
Para responder correctamente a esta pregunta, debemos analizar la prueba bajo dos condiciones diferentes: primero, la página tiene solo una transacción de base de datos; segundo, la página tiene múltiples transacciones de base de datos;
En el ejemplo anterior, creamos un objeto Connection independiente y lo asignamos a la propiedad ActiveConnection del Recordset. Sin embargo, como se muestra en ADO__03.asp, también podemos asignar la cadena de conexión directamente a la propiedad ActiveConnection, eliminando el paso adicional de inicializar y configurar el objeto Conexión en el script.
objRS.ActiveConnection = Aplicación(Conexión)
Aunque el objeto Recordset aún necesita crear una conexión, la creación en este momento se lleva a cabo en condiciones altamente optimizadas. Como resultado, la sobrecarga de la página se redujo otro 23% en comparación con la prueba anterior y, como se esperaba, el tiempo de visualización de un solo registro no cambió sustancialmente.
Por tanto, nuestra segunda regla es la siguiente:
lSi solo usa un conjunto de registros, asigne directamente la cadena de conexión a la propiedad ActiveConnection.
A continuación, comprobamos si las reglas anteriores siguen siendo válidas cuando la página utiliza varios conjuntos de registros. Para probar esta situación, introducimos un bucle FOR para repetir el ejemplo anterior 10 veces. En esta prueba veremos tres variaciones:
Primero, como se muestra en ADO__04.asp, el objeto Conexión se establece y se destruye en cada bucle:
Copie el código de código de la siguiente manera:
Yo tenue
Para i = 1 a 10
Establecer objConn = Server.CreateObject(ADODB.Connection)
objConn.Abrir aplicación (Conexión)
Establecer objRS = Server.CreateObject(ADODB.Recordset)
objRS.ActiveConnection = objConn
objRS.CursorType = 0 'adOpenForwardOnly
objRS.LockType = 1 'adLockReadOnly
objRS.Aplicación abierta (SQL)
Si objRS.EOF Entonces
Respuesta.Escribir (No se encontraron registros)
Demás
'escribir encabezados
...
'escribir datos
...
Terminar si
objRS.Cerrar
Establecer objRS = Nada
objConn.Cerrar
Establecer objConn = Nada
Próximo
En segundo lugar, como se muestra en ADO__05.asp, cree un objeto Conexión fuera del bucle y comparta este objeto con todos los conjuntos de registros:
Copie el código de código de la siguiente manera:
Establecer objConn = Server.CreateObject(ADODB.Connection)
objConn.Abrir aplicación (Conexión)
Yo tenue
Para i = 1 a 10
Establecer objRS = Server.CreateObject(ADODB.Recordset)
objRS.ActiveConnection = objConn
objRS.CursorType = 0 'adOpenForwardOnly
objRS.LockType = 1 'adLockReadOnly
objRS.Aplicación abierta (SQL)
Si objRS.EOF Entonces
Respuesta.Escribir (No se encontraron registros)
Demás
'escribir encabezados
...
'escribir datos
...
Terminar si
objRS.Cerrar
Establecer objRS = Nada
Próximo
objConn.Cerrar
Establecer objConn = Nada
En tercer lugar, como se muestra en ADO__06.asp, asigne la cadena de conexión a la propiedad ActiveConnection en cada bucle:
Copie el código de código de la siguiente manera:
Yo tenue
Para i = 1 a 10
Establecer objRS = Server.CreateObject(ADODB.Recordset)
objRS.ActiveConnection = Aplicación(Conexión)
objRS.CursorType = 0 'adOpenForwardOnly
objRS.LockType = 1 'adLockReadOnly
objRS.Aplicación abierta (SQL)
Si objRS.EOF Entonces
Respuesta.Escribir (No se encontraron registros)
Demás
'escribir encabezados
...
'escribir datos
...
Terminar si
objRS.Cerrar
Establecer objRS = Nada
Próximo
Como podemos adivinar, crear y eliminar objetos de conexión dentro de un bucle es la forma menos eficiente. Sin embargo, sorprendentemente, asignar la cadena de conexión directamente a la propiedad ActiveConnection dentro del bucle es sólo un poco más lento que compartir un único objeto Connection.
No obstante, la tercera regla debería ser:
lCuando se utilizan varios conjuntos de registros en la misma página, cree un único objeto de conexión y compártalo a través de la propiedad ActiveConnection.
6. ¿Qué tipo de cursor y método de bloqueo de registros son los más eficientes?
En todas las pruebas hasta ahora solo hemos utilizado cursores de avance para acceder al conjunto de registros. Hay tres tipos de cursores proporcionados por ADO para conjuntos de registros: cursores desplazables estáticos, cursores desplazables dinámicos y cursores de conjunto de claves. Cada cursor proporciona diferentes funciones, como acceder al registro anterior y al siguiente, si se pueden ver modificaciones de datos por parte de otros programas, etc. Sin embargo, una discusión detallada de las funciones de cada tipo de cursor está fuera del alcance de este artículo. La siguiente tabla es un análisis comparativo de varios tipos de cursor.
Todos los demás tipos de cursor requieren una sobrecarga adicional en comparación con los cursores de solo avance, y estos cursores generalmente son más lentos dentro de los bucles. Por lo tanto, nos gustaría compartir con usted la siguiente advertencia: Nunca piense así; bueno, a veces usaré cursores dinámicos, por lo que siempre usaré este cursor.
El mismo sentimiento se aplica a la elección del método de bloqueo de registros. La prueba anterior solo utilizó el método de bloqueo de solo lectura, pero hay otros tres métodos: procesamiento por lotes conservador, abierto y abierto. Al igual que los tipos de cursor, estos métodos de bloqueo proporcionan diferentes funciones y control sobre el trabajo con datos de conjuntos de registros.
Llegamos a las siguientes reglas:
lUtilice el tipo de cursor y el método de bloqueo de registros más simples y adecuados para la tarea.
7. ¿Qué método es mejor utilizar para extraer un conjunto de registros?
Hasta ahora hemos estado extrayendo conjuntos de registros mediante la creación de objetos Recordset, pero ADO también proporciona métodos indirectos de extracción de conjuntos de registros. La siguiente prueba compara ADO__03.asp y la creación de un conjunto de registros directamente desde el objeto Conexión (CONN_01.asp):
Copie el código de código de la siguiente manera:
Establecer objConn = Server.CreateObject(ADODB.Connection)
objConn.Abrir aplicación (Conexión)
Establecer objRS = objConn.Execute(Aplicación(SQL))
Puede ver que la sobrecarga de la página ha aumentado ligeramente y el tiempo de visualización de un solo registro no ha cambiado.
Echemos un vistazo a la creación de un objeto de conjunto de registros (CMD__02.asp) directamente desde el objeto Comando:
Copie el código de código de la siguiente manera:
Establecer objCmd = Server.CreateObject(ADODB.Command)
objCmd.ActiveConnection = Aplicación(Conexión)
objCmd.CommandText = Aplicación (SQL)
Establecer objRS = objCmd.Execute
Del mismo modo, la sobrecarga de la página aumenta ligeramente sin cambios sustanciales en el tiempo de visualización de un solo registro. La diferencia de rendimiento entre los dos últimos métodos es pequeña, pero tenemos una cuestión importante que considerar.
Al crear un conjunto de registros a través de la clase Recordset, podemos controlar el procesamiento del conjunto de registros con la mayor flexibilidad. Dado que los dos últimos métodos no logran un rendimiento abrumador, consideramos principalmente el tipo de cursor y el método de bloqueo de registros devueltos de forma predeterminada. En algunas ocasiones, el valor predeterminado no es necesariamente el más ideal.
Por lo tanto, a menos que existan razones especiales para elegir entre los dos últimos métodos, recomendamos considerar las siguientes reglas:
l Cree una instancia del conjunto de registros a través de la clase ADODB.Recordset para obtener el mejor rendimiento y flexibilidad.
8. ¿Debo utilizar un conjunto de registros local?
ADO permite el uso de conjuntos de registros locales (cliente). En este momento, la consulta extraerá todos los datos del conjunto de registros. Una vez completada la consulta, la conexión se puede cerrar inmediatamente y se pueden usar cursores locales para acceder a los datos. el futuro, lo que aporta comodidad para liberar la conexión. El uso de conjuntos de registros locales es importante para acceder a servicios de datos remotos que requieren que los datos se utilicen sin conexión, pero ¿será también útil para aplicaciones normales?
A continuación agregamos el atributo CursorLocation y cerramos la conexión (CLIENT1.asp) después de abrir el conjunto de registros:
Copie el código de código de la siguiente manera:
Establecer objRS = Server.CreateObject(ADODB.Recordset)
objRS.CursorLocation = 2' adUseClient
objRS.ActiveConnection = Aplicación(Conexión)
objRS.LockType = 1?'
objRS.Aplicación abierta (SQL)
objRS.ActiveConnection = Nada
En teoría, este enfoque beneficiaría la eficiencia por dos razones: primero, evita solicitar datos repetidamente a través de la conexión al moverse entre registros; segundo, facilita los requisitos de recursos; Sin embargo, de la tabla anterior se desprende que el uso de un conjunto de registros local obviamente no ayudará a mejorar la eficiencia. Esto puede deberse a que cuando se utiliza un conjunto de registros local, el cursor siempre se vuelve de tipo estático sin importar cuál sea la configuración del programa.
La regla 6 es la siguiente:
lEsto debe evitarse a menos que realmente se requiera la localización del conjunto de registros.
10. ¿Qué método es el más eficiente para hacer referencia a valores de campo en un conjunto de registros?
10.1 Pruebas
Hasta ahora nos hemos referido a los valores de campo en el conjunto de registros por nombre. Dado que este método requiere encontrar el campo correspondiente cada vez, no es muy eficiente. Para demostrar esto, en la siguiente prueba hacemos referencia al valor de un campo por su índice en la colección (ADO__08.asp):
Copie el código de código de la siguiente manera:
'escribir datos
Hacer mientras no objRS.EOF
Respuesta.Escribir(_
<TR> & _
<TD> & objRS(0) & </TD> & _
<TD> & objRS(1) & </TD> & _
<TD> & objRS(2) & </TD> & _
<TD> & objRS(3) & </TD> & _
<TD> & objRS(4) & </TD> & _
<TD> & objRS(5) & </TD> & _
<TD> & objRS(6) & </TD> & _
</TR> _
)
objRS.MoveNext
Bucle
Como era de esperar, también hay un pequeño cambio en la sobrecarga de la página (quizás debido a una ligera reducción en el código). Sin embargo, la mejora en el tiempo de visualización con este enfoque es bastante notable.
En la siguiente prueba, vinculamos todos los campos a variables individualmente (ADO__09.asp):
Copie el código de código de la siguiente manera:
Si objRS.EOF Entonces
Respuesta.Escribir (No se encontraron registros)
Demás
'escribir encabezados
...
fld0 tenue
fld1 tenue
fld2 tenue
fld3 tenue
fld4 tenue
fld5 tenue
fld6 tenue
Establecer fld0 = objRS(0)
Establecer fld1 = objRS(1)
Establecer fld2 = objRS(2)
Establecer fld3 = objRS(3)
Establecer fld4 = objRS(4)
Establecer fld5 = objRS(5)
Establecer fld6 = objRS(6)
'escribir datos
Hacer mientras no objRS.EOF
Respuesta.Escribir(_
<TR> & _
<TD> & fld0 & </TD> & _
<TD> & fld1 & </TD> & _
<TD> & fld2 & </TD> & _
<TD> & fld3 & </TD> & _
<TD> & fld4 & </TD> & _
<TD> & fld5 & </TD> & _
<TD> & fld6 & </TD> & _
</TR> _
)
objRS.MoveNext
Bucle
Establecer fld0 = Nada
Establecer fld1 = Nada
Establecer fld2 = Nada
Establecer fld3 = Nada
Establecer fld4 = Nada
Establecer fld5 = Nada
Establecer fld6 = Nada
Respuesta.Escribir(</TABLE>)
Terminar si
Este es el mejor récord hasta el momento. Tenga en cuenta que el tiempo de visualización de un solo registro se ha reducido a menos de 0,45 milisegundos.
Todos los scripts anteriores requieren cierta comprensión de la construcción del conjunto de registros de resultados. Por ejemplo, utilizamos nombres de campos directamente en los encabezados de las columnas para hacer referencia a cada valor de campo individualmente. En la siguiente prueba, no solo se obtienen los datos del campo atravesando la colección de campos, sino que también se obtienen los títulos de los campos de la misma manera. Esta es una solución más dinámica (ADO__10.asp).
Copie el código de código de la siguiente manera:
Si objRS.EOF Entonces
Respuesta.Escribir (No se encontraron registros)
Demás
'escribir encabezados Response.Write(<TABLE BORDER=1><TR>)
Para cada objFld en objRS.Fields
Respuesta.Escribir(<TH> & objFld.name & </TH>)
Próximo
Respuesta.Escribir(</TR>)
'escribir datos
Hacer mientras no objRS.EOF
Respuesta.Escribir(<TR>)
Para cada objFld en objRS.Fields
? Respuesta.Escribir(<TD> & objFld.value & </TD>)
Próximo
Respuesta.Escribir(</TR>)
objRS.MoveNext
Bucle
Respuesta.Escribir(</TABLE>)
Terminar si
Como puede ver, el rendimiento del código ha disminuido, pero sigue siendo más rápido que ADO__07.asp.
El siguiente ejemplo de prueba es una combinación de los dos métodos anteriores. Continuaremos manteniendo la característica dinámica mientras mejoramos el rendimiento guardando referencias de campos en matrices asignadas dinámicamente:
Copie el código de código de la siguiente manera:
Si objRS.EOF Entonces
Respuesta.Escribir (No se encontraron registros)
Demás
Dim fldCount
fldCount = objRS.Fields.Count
campo tenue()
ReDim fld(fldCount)
Yo tenue
Para i = 0 a fldCount-1
Establecer fld(i) = objRS(i)
Próximo
'escribir encabezados
Response.Write(<TABLE BORDER=1><TR>) Para i = 0 a fldCount-1
Respuesta.Escribir(<TH> & fld(i).nombre & </TH>)
Próximo
Respuesta.Escribir(</TR>)
'escribir datos
Hacer mientras no objRS.EOF
Respuesta.Escribir(<TR>)
Para i = 0 a fldCount-1
Respuesta.Escribir(<TD> & fld(i) & </TD>)
Próximo
Respuesta.Escribir(</TR>)
objRS.MoveNext
Bucle
Para i = 0 a fldCount-1
Establecer fld(i) = Nada
Próximo
Respuesta.Escribir(</TABLE>)
Terminar si
Si bien no supera a los mejores ejemplos anteriores, es más rápido que los primeros ejemplos y tiene la ventaja de procesar dinámicamente cualquier conjunto de registros.
En comparación con el código de prueba anterior, el siguiente código de prueba ha cambiado fundamentalmente. Utiliza el método GetRows del objeto Recordset para completar la matriz para la iteración sobre los datos, en lugar de acceder directamente al Recordset. Tenga en cuenta que Recordset se establece en Nothing inmediatamente después de llamar a GetRows, lo que significa que los recursos del sistema se liberan lo antes posible. Además, tenga en cuenta que la primera dimensión de la matriz representa los campos y la segunda dimensión representa las filas (ADO__12.asp).
Copie el código de código de la siguiente manera:
Si objRS.EOF Entonces
Respuesta.Escribir (No se encontraron registros)
objRS.Cerrar
Establecer objRS = Nada
Demás
'escribir encabezados
...
'establecer matriz
ArrRS tenue
arrRS = objRS.GetRows
'cerrar el conjunto de registros temprano
objRS.Cerrar
Establecer objRS = Nada
'escribir datos
DimnumFilas
DimnumFlds
fila tenue
campo oscuro
numFlds = Ubound(arrRS, 1)
numFilas = Ubound(arrRS, 2)
Para fila = 0 a numFilas
Respuesta.Escribir(<TR>)
Para fld = 0 a numFlds
Respuesta.Escribir(<TD> & arrRS(fld, fila) & </TD>)
Próximo
Respuesta.Escribir(</TR>)
Próximo
Respuesta.Escribir(</TABLE>)
Terminar si
Cuando se utiliza el método GetRows, todo el conjunto de registros se extrae en una matriz. Aunque pueden ocurrir problemas de recursos cuando el conjunto de registros es extremadamente grande, acceder a los datos en un bucle es realmente más rápido porque se cancelan las llamadas a funciones como MoveNext y la verificación de EOF.
La velocidad tiene un costo: ahora se pierden los metadatos del conjunto de registros. Para resolver este problema, podemos extraer la información del encabezado del objeto del conjunto de registros antes de llamar a GetRows; además, el tipo de datos y otra información también se pueden extraer por adelantado; Tenga en cuenta también que la ventaja de rendimiento en las pruebas sólo se produce cuando el conjunto de registros es mayor.
En la última prueba de este conjunto, utilizamos el método GetString del conjunto de registros. El método GetString extrae todo el conjunto de registros en una cadena grande y le permite especificar el delimitador (ADO__13.asp):
Copie el código de código de la siguiente manera:
Si objRS.EOF Entonces
Respuesta.Escribir (No se encontraron registros)
objRS.Cerrar
Establecer objRS = Nada
Demás
'escribir encabezados
...
'establecer matriz
Dim strTable
strTable = objRS.GetString (2, , </TD><TD>, </TD></TR><TR><TD>)
'cerrar el conjunto de registros temprano
objRS.Cerrar
Establecer objRS = Nada
Respuesta.Write(strTable & </TD></TR></TABLE>)
Terminar si