2011-03-01 8 views
8

descripción de la aplicación:
Tengo una aplicación de Delphi que permite a un usuario definir una serie de consultas, y ejecutarlos simultáneamente a través de múltiples bases de datos MySQL. Existe un límite en el número de subprocesos que se pueden ejecutar a la vez (que el usuario puede establecer). El usuario selecciona las consultas que se ejecutarán y los sistemas en los que se ejecutarán las consultas. Cada subproceso ejecuta la consulta especificada en el sistema especificado utilizando un componente TADOQuery.aplicación de base de multiproceso Delphi no con grandes cantidades de datos

Descripción del problema:
Cuando las consultas recuperan un bajo número de registros, la aplicación funciona muy bien, incluso cuando se presentan gran cantidad de hilos (hasta aproximadamente 100). La aplicación también puede manejar un mayor número de registros (más de 150,000) siempre que solo se ejecuten unos pocos hilos (hasta aproximadamente 8) a la vez. Sin embargo, cuando el usuario ejecuta más de 10 consultas al mismo tiempo (es decir, más de 10 hilos) y cada hilo recupera más de 150,000 registros, comenzamos a recibir errores. Estos son los mensajes de error específicos que hemos encontrado hasta ahora:

a: Not enough storage is available to complete this operation
b: OLE error 80040E05
c: Unspecified error
d: Error de creación del hilo: Not enough storage is available to process this command
e: Object was open
f: ODBC Driver does not support the requested properties

Evidentemente, los errores se deben a una combinación de factores: número de subprocesos, cantidad de datos recuperados por subproceso y posiblemente la configuración del servidor MySQL.

La pregunta principal realmente es ¿por qué ocurren los errores? Aprecio que parece estar de alguna manera relacionado con los recursos, pero dados los diferentes errores que se están devolviendo, me gustaría saber exactamente por qué están apareciendo los errores. Se trata de recursos en la PC, o algo relacionado con la configuración del servidor, por ejemplo.

La siguiente pregunta es ¿qué podemos hacer para evitar problemas? Actualmente estamos reduciendo la aplicación al disminuir el número de subprocesos que se pueden ejecutar al mismo tiempo. No podemos obligar al usuario a recuperar menos registros ya que las consultas están totalmente definidas por el usuario y si quieren recuperar 200,000 registros, entonces eso depende de ellos, por lo que no hay mucho que podamos hacer sobre ese lado de las cosas. De manera realista, no queremos reducir la velocidad de la aplicación porque la mayoría de los usuarios recuperarán pequeñas cantidades de datos, y no queremos que la aplicación se ralentice para que ellos la usen, y aunque el número de subprocesos puede ser cambiado por el usuario, preferimos llegar a la raíz del problema y tratar de solucionarlo sin tener que depender de ajustar la configuración todo el tiempo.

+0

Cualquier posibilidad de que pueda establecer 'TADOQuery.CursorType: = ctOpenForwardOnly'? Podría ayudar con la asignación de recursos. –

+0

¿Puede mostrarnos el código utilizado para configurar los hilos, las conexiones y las consultas? –

Respuesta

5

Parece que está cargando una gran cantidad de datos del lado del cliente. Es posible que requieran que se almacenen en la memoria del cliente (especialmente si utiliza cursores bidireccionales), y en una aplicación de 32 bits que podría no ser suficiente, dependiendo del tamaño de fila promedio y qué tan eficiente es la biblioteca para almacenar filas. Por lo general, la mejor manera de llevar a cabo el trabajo de la base de datos es realizar eso en el servidor directamente, sin recuperar datos para el cliente. Por lo general, las bases de datos tienen un sistema de caché eficiente y pueden escribir datos en el disco cuando no encajan en la memoria. ¿Por qué recuperas 150000 filas a la vez? Podría usar un mecanismo para transferir datos solo cuando el usuario realmente acceda a ellos (tipo de búsqueda a través de datos), para evitar grandes cantidades de memoria "desperdiciada".

+0

Según tengo entendido, el volumen de datos no es un problema con el menor número de subprocesos: 'La aplicación puede ... manejar un mayor número de registros (150,000+) siempre que solo se ejecuten unos pocos hilos (hasta aproximadamente 8) al mismo tiempo. – mjn

+0

Eso es bastante obvio. Los subprocesos comparten el espacio de direcciones de su proceso. Mientras más hilo cree, menor espacio de memoria tendrá cada hilo. –

+0

Lo que estaba buscando era algo específico sobre exactamente qué estaba causando el error, ya que mi gerente me está pidiendo detalles específicos. Sin embargo, mi respuesta a él sobre el número de subprocesos utilizados y la cantidad de datos que se recuperan por subproceso parece ser la causa principal, por lo que estoy satisfecho con esta respuesta. Para su información, en algunos casos necesitamos recuperar grandes cantidades de datos para que el informe pueda archivarse en la PC y posteriormente ser procesado sin conexión. Sin embargo, creo que el mecanismo de recuperación puede ser más eficiente, así que estaré investigando esto. Gracias por la respuesta. – Jeedee

4

Esto tiene perfecto sentido (el hecho de que tenga problemas, no los errores específicos).Piénselo bien: tiene el equivalente de 10 conexiones de base de datos (1 por hilo), cada una de las cuales recibe 150,000 filas de datos (1,500,000 filas en total) a través de una única conexión de red. Incluso si no está utilizando los cursores del lado del cliente y las filas son pequeñas (solo unas pocas columnas pequeñas), se trata de un ENORME flujo de datos a través de una única interfaz de red, y un gran golpe en la memoria en la computadora cliente.

Sospecho que los mensajes de error son incorrectos, del mismo modo que a veces tiene una infracción de acceso causada por una sobrescritura de memoria en otra ubicación de código.

0

Dependiendo de su DBMS, para ayudar con el problema, podría utilizar las cláusulas LIMIT/TOP sql para limitar la cantidad de datos devueltos.

0

cosas que haría:

  • escribir una aplicación de prueba muy simple que sólo utiliza las partes necesarias de la creación de la conexión/consulta (con hilos), esto eliminaría todos los efectos secundarios causados ​​por otras partes del su software

  • uso de una capa de acceso a la base de datos diferente en lugar de ODBC, para averiguar si el controlador ODBC es la causa raíz del problema

  • parece que el uso de memoria es sin proble m cuando el número de subprocesos es bajo: para verificar esto, también mediría/calcularía los requisitos de memoria de los registros, los compararé con el uso de memoria de la aplicación en el sistema operativo. Por ejemplo, si las pruebas muestran que cuatro hilos pueden consultar con seguridad 1,5 GB de datos totales sin problemas, pero fallan diez hilos con menos de 0,5 GB de datos totales, yo diría que es un problema de subprocesamiento

Cuestiones relacionadas