Problema al usar un WebService

07/09/2006 - 09:03 por Asier | Informe spam
Hola grupo,

Tengo un Servicio Web, con un metodo publico que ejecuta un
procedimiento almacenado de Sql server. Este procedimiento es una select
compleja que me trae 150.000 registros de la base de datos. El servicio web
tarda en ejecutarse aproximadamente 10 segundos.

Ahora bien, cuando ejecuto el metodo del servicio web desde una
aplicacion WindowsForms, el servicio web se ejecuta igual pero al devolver
el resultado del proc almacenado en un dataset (el metodo web devuleve un
dataset) el programa se queda parado por lo menos 1 minuto.

Me gustaría saber que puede pasar, y que soluciones tengo.

Gracias y Saludos,

Asier

Preguntas similare

Leer las respuestas

#1 Alberto Poblacion
07/09/2006 - 09:30 | Informe spam
"Asier" wrote in message
news:
Tengo un Servicio Web, con un metodo publico que ejecuta un
procedimiento almacenado de Sql server. Este procedimiento es una select
compleja que me trae 150.000 registros de la base de datos. El servicio
web
tarda en ejecutarse aproximadamente 10 segundos.

Ahora bien, cuando ejecuto el metodo del servicio web desde una
aplicacion WindowsForms, el servicio web se ejecuta igual pero al devolver
el resultado del proc almacenado en un dataset (el metodo web devuleve un
dataset) el programa se queda parado por lo menos 1 minuto.

Me gustaría saber que puede pasar, y que soluciones tengo.



Si lo he entendido bien, tu servicio web tarda 10 segundos en traer los
150.000 registros desde el servidor de base de datos al servidor web, y
tarda 1 minuto en transferir esos mismos 150.000 registros desde el servidor
web al PC cliente.
No veo el motivo de la extrañeza. La relación de tiempos parece bastante
razonable: El protocolo que transfiere datos desde la base de datos es
sumamente compacto, mientras que la transferencia desde el servidor web al
cliente codifica los mismos datos en XML con lo cual se "inflan" muchísimo.
No es extraño que esta segunda transferencia tarde 6 veces más que la
primera, incluso sin tener en cuenta las posibles diferencias de velocidad
entre las dos redes (servidor bd <-> servidor web y servidor web <-> pc
cliente).

¿Has hecho las cuentas de cuánto mide cada registro una vez codificado
en XML? Es fácil que mida 1000 bytes. Multiplica por 150.000 registros y
resulta que para transmitir tu dataset se necesita enviar 150 Megabytes
desde el servidor al cliente. 1 minuto para transferir 150 Megabytes no me
parece que sea lento.
Respuesta Responder a este mensaje
#2 Jesús López
07/09/2006 - 12:06 | Informe spam
Alberto tiene toda la razón, no hay nada de qué extrañarse.

Lo que está claro es que 1 minuto parece una espera inacteptable, a no ser
que llames al procedimiento almacenado una vez al año, claro está. Por tanto
hay que buscar una solución.

La solución podríamos resumirla en una sóla palabra: rediseño.

¿Qué clase de rediseño? Bueno, el problema es que para poder elegir el
diseño más adecuado necesitaría conocer todos los detalles, y de momento no
has proporcionado muchos. En cualquier caso lo primero que habría que
plantearse es si realmente es imprescindible la transferencia de 150.000
registros de golpe. Si se pudieran filtrar de alguna manera esos registros,
por ejemplo, preguntando al usuario por alguna condición de búsqueda, el
problema estaría solucionado al reducir el número de registros.

Los detalles que necesitaría conocer son los siguientes:

¿Qué se hace con los 150.000 registros en la aplicación Windows Forms?
¿Cual es la instrucción select que hay en el procedimiento almacenado?
¿Qué frecuencia de actualización se produce en las tablas base de la
instrucción select?
Cualquier otro detalle que consideres relevante.

Algunas posibles soluciones serían:

(1) Usar paginación
(2) Enviar la informacíón de forma más compacta. Por ejemplo guardar los
datos en forma binaria en un archivo, comprimirlo en un zip y que lo
descargue el cliente.
(3) Usar replicación. Por ejemplo instalar SQL Server 2005 Express en el
cliente, e implementar replicación de mezcla.
(4) Cachear datos de forma persistente en el cliente. Por ejemplo usar una
base de datos de SQLite en el cliente y actualizarla cuando se produzcan
cambios en los datos del servidor.


Saludos:

Jesús López


"Asier" escribió:

Hola grupo,

Tengo un Servicio Web, con un metodo publico que ejecuta un
procedimiento almacenado de Sql server. Este procedimiento es una select
compleja que me trae 150.000 registros de la base de datos. El servicio web
tarda en ejecutarse aproximadamente 10 segundos.

Ahora bien, cuando ejecuto el metodo del servicio web desde una
aplicacion WindowsForms, el servicio web se ejecuta igual pero al devolver
el resultado del proc almacenado en un dataset (el metodo web devuleve un
dataset) el programa se queda parado por lo menos 1 minuto.

Me gustaría saber que puede pasar, y que soluciones tengo.

Gracias y Saludos,

Asier



Respuesta Responder a este mensaje
#3 Asier
07/09/2006 - 15:46 | Informe spam
hola,

Antes de nada, gracias por vuestra ayuda. La pantalla recoge accesos a
un edificio y claro, si consultan todos los accesos de un año, hay
bastantes. Os podeis imaginar que la tablña está continuamente recibiendo
nuevos registros, eso si, sobre esa tabla no hay nunca ni deletes ni
updates, solo insert (muy frecuentes) y select (menos frecuentes). Tienen
filtros para seleccionar por fechas, etc. La select esta bastante optimizada
pero el equipo que tengo de pruebas tiene todo, base de datos, servicio web
y aplicación winforms, así que no puede ser nada de la red

Gracias,

Asier


"Jesús López" escribió en el mensaje
news:
Alberto tiene toda la razón, no hay nada de qué extrañarse.

Lo que está claro es que 1 minuto parece una espera inacteptable, a no ser
que llames al procedimiento almacenado una vez al año, claro está. Por


tanto
hay que buscar una solución.

La solución podríamos resumirla en una sóla palabra: rediseño.

¿Qué clase de rediseño? Bueno, el problema es que para poder elegir el
diseño más adecuado necesitaría conocer todos los detalles, y de momento


no
has proporcionado muchos. En cualquier caso lo primero que habría que
plantearse es si realmente es imprescindible la transferencia de 150.000
registros de golpe. Si se pudieran filtrar de alguna manera esos


registros,
por ejemplo, preguntando al usuario por alguna condición de búsqueda, el
problema estaría solucionado al reducir el número de registros.

Los detalles que necesitaría conocer son los siguientes:

¿Qué se hace con los 150.000 registros en la aplicación Windows Forms?
¿Cual es la instrucción select que hay en el procedimiento almacenado?
¿Qué frecuencia de actualización se produce en las tablas base de la
instrucción select?
Cualquier otro detalle que consideres relevante.

Algunas posibles soluciones serían:

(1) Usar paginación
(2) Enviar la informacíón de forma más compacta. Por ejemplo guardar los
datos en forma binaria en un archivo, comprimirlo en un zip y que lo
descargue el cliente.
(3) Usar replicación. Por ejemplo instalar SQL Server 2005 Express en el
cliente, e implementar replicación de mezcla.
(4) Cachear datos de forma persistente en el cliente. Por ejemplo usar una
base de datos de SQLite en el cliente y actualizarla cuando se produzcan
cambios en los datos del servidor.


Saludos:

Jesús López


"Asier" escribió:

> Hola grupo,
>
> Tengo un Servicio Web, con un metodo publico que ejecuta un
> procedimiento almacenado de Sql server. Este procedimiento es una select
> compleja que me trae 150.000 registros de la base de datos. El servicio


web
> tarda en ejecutarse aproximadamente 10 segundos.
>
> Ahora bien, cuando ejecuto el metodo del servicio web desde una
> aplicacion WindowsForms, el servicio web se ejecuta igual pero al


devolver
> el resultado del proc almacenado en un dataset (el metodo web devuleve


un
> dataset) el programa se queda parado por lo menos 1 minuto.
>
> Me gustaría saber que puede pasar, y que soluciones tengo.
>
> Gracias y Saludos,
>
> Asier
>
>
>
Respuesta Responder a este mensaje
#4 Alberto Poblacion
07/09/2006 - 16:19 | Informe spam
"Asier" wrote in message
news:%
Antes de nada, gracias por vuestra ayuda. La pantalla recoge accesos a
un edificio y claro, si consultan todos los accesos de un año, hay
bastantes. Os podeis imaginar que la tablña está continuamente recibiendo
nuevos registros, eso si, sobre esa tabla no hay nunca ni deletes ni
updates, solo insert (muy frecuentes) y select (menos frecuentes). Tienen
filtros para seleccionar por fechas, etc. La select esta bastante
optimizada
pero el equipo que tengo de pruebas tiene todo, base de datos, servicio
web
y aplicación winforms, así que no puede ser nada de la red



Aunque no haya red, mover 150 megabytes a través del stack de IP del
ordenador sigue siendo costoso. especialmente si además tienen que irse
procesando sobre la marcha (la CPU tiene que codificar todos esos datos en
XML y luego volver a decodificar el XML reconstruyendo los datos.
Aparte de eso, el ordenador tendrá varias copias en memoria (el dataset
(con los strings en Unicode), más el texto en xml, más la copia de ese xml
recibida por el programa cliente, más el resultado de decodificar ese xml en
el dataset del lado cliente. Por no hablar del caché de páginas del servidor
SQL, y, si el dataset está vinculado a un control en el lado cliente, el
espacio ocupado por la representación de los datos en ese control. Total,
que a lo mejor estás manejando un gigabyte de datos en la memoria de ese
ordenador, lo cual posiblemente va a ocasionar una gran cantidad de swapping
que también va a enlentecer el proceso.
En resumen, estoy de acerdo con Jesús en que es preferible cambiar el
diseño de la aplicación; mover semejante volumen de datos a través de una
única llamada a un servicio web va a resultar lento en cualquier caso.
Respuesta Responder a este mensaje
#5 Jesús López
07/09/2006 - 17:16 | Informe spam
Yo lo que haría sería tener una copia actualizada de los datos en los
clientes en una base de datos de SQLite y haría las consultas sobre la base
de datos local en vez de "molestar" al servidor cada vez.

Implementar esta copia actualizada es sencillo, teniendo en cuenta que en la
tabla las únicas modificaciones son las inserciones. Sería cuestión de tener
un método en el servicio web como este:

Public Function ObtenerAccesos( IdUltimaSincronización As Integer ) As
Dataset

Básicamente este método devolvería los accesos producidos desde la última
sincronización. Una select similar a esta:

SELECT FROM LaTabla WHERE Id > @UltimaSincronización

Todo esto suponiendo que LaTabla tiene un Id autonumérico.

Las aplicaciones cliente podrían sincronizarse cada vez que arrancan o cada
vez que se hace una consulta sobre los accesos. Lo que tienen que hacer es
guardar la última sincronización, es decir, el ID mayor e insertar los
registros en la base de datos local.

SQLite es un sistema de gestión de base de datos "embedded" y "open source"
que no requiere ninguna configuración. Con solo copiar el archivo
System.Data.SQLite.dll en el directorio de la aplicación ya está. Además es
tremendamente eficiente en cargas masivas de datos y en lecturas y admite
encriptación basada en contraseñas. Aquí puedes encontrar el proveedor de
datos nativo para ADO.NET 2.0:

http://sqlite.phxsoftware.com/

Saludos:

Jesús López


"Alberto Poblacion"
escribió en el mensaje news:
"Asier" wrote in message
news:%
Antes de nada, gracias por vuestra ayuda. La pantalla recoge accesos a
un edificio y claro, si consultan todos los accesos de un año, hay
bastantes. Os podeis imaginar que la tablña está continuamente recibiendo
nuevos registros, eso si, sobre esa tabla no hay nunca ni deletes ni
updates, solo insert (muy frecuentes) y select (menos frecuentes). Tienen
filtros para seleccionar por fechas, etc. La select esta bastante
optimizada
pero el equipo que tengo de pruebas tiene todo, base de datos, servicio
web
y aplicación winforms, así que no puede ser nada de la red



Aunque no haya red, mover 150 megabytes a través del stack de IP del
ordenador sigue siendo costoso. especialmente si además tienen que irse
procesando sobre la marcha (la CPU tiene que codificar todos esos datos en
XML y luego volver a decodificar el XML reconstruyendo los datos.
Aparte de eso, el ordenador tendrá varias copias en memoria (el dataset
(con los strings en Unicode), más el texto en xml, más la copia de ese xml
recibida por el programa cliente, más el resultado de decodificar ese xml
en el dataset del lado cliente. Por no hablar del caché de páginas del
servidor SQL, y, si el dataset está vinculado a un control en el lado
cliente, el espacio ocupado por la representación de los datos en ese
control. Total, que a lo mejor estás manejando un gigabyte de datos en la
memoria de ese ordenador, lo cual posiblemente va a ocasionar una gran
cantidad de swapping que también va a enlentecer el proceso.
En resumen, estoy de acerdo con Jesús en que es preferible cambiar el
diseño de la aplicación; mover semejante volumen de datos a través de una
única llamada a un servicio web va a resultar lento en cualquier caso.


Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida