2012-02-13 28 views
6

(Utilizando Delphi 2010 + última SQLite en el modo WAL)alternativa SQLite con la escritura simultánea (Delphi)

estoy usando (puerto de Delphi SQLite) DISQLite con mi solicitud cliente multi-threading (aún no se en libertad, por lo que puede cambiar el motor de base de datos si realmente tengo a)

Mi perfilador dice claramente que es una decisión estúpida, rastreé esto a 2-3 sentencias SQL muy simples que vuela cuando se ejecuta en una sola aplicación enhebrada, pero debido a que los hilos están bloqueados/esperando (SQLite realmente no funciona bien con múltiples hilos intentando escribir simultáneamente)

hice todo lo posible para optimizar mi código/evitar los cuellos de botella, pero después de varias semanas de duro trabajo, ahora me pregunto si no es simplemente más fácil para volcar SQLite & elegir un motor de base de datos diferente (?)

Mis requisitos son:

  1. ÁCIDO
  2. Muy buena lectura simultánea/escritura (nivel de grabación) de apoyo
  3. (muy) rápida & motor de base de datos estable
  4. árbol B
  5. Delphi 2010 apoyo

sólo estoy usando INSERT/UPDATE/DELETE comandos básicos con índices, nada de lujos. Así que mis requisitos de SQL son relativamente básicos (no necesito unirme u otras cosas "más avanzadas" de sql).

También estoy abierto a soluciones NQL, siempre y cuando cumpla con los requisitos mencionados anteriormente.

Mi investigación llevó a Berkley DB, que es, si entendí correctamente, una versión modificada de SQLite con soporte de escritura concurrente, pero el problema es que no es realmente para delphi.

También leí acerca de Gabinete de Kyoto, pero de nuevo, no hay soporte delphi :(

Cualquier sugerencia sería más que bienvenido,

Gracias

+0

No estoy seguro acerca de las fijaciones de Delphi, pero puedes echar un vistazo a http://en.wikipedia.org/wiki/Berkeley_DB (tiene enlaces para casi todo lo demás) –

+1

@JoachimIsaksson: Gracias, sí lo hice en BDB en wikipedia, encontré esto: http://www.demonak.com/delphi/berkeleydb.en.shtml y "AnyDAC para soporte de DB de Delphi Berkeley", pero no estoy seguro de que esto sea lo que quiero (no para mencionar el costo de la licencia ... :() – TheDude

+0

Lo uso para código abierto y no vi en su pregunta que especificó código abierto o no, pero sí, definitivamente podría ver los costos de licencias de Oracle como un problema. para código abierto en la misma situación, aunque :) –

Respuesta

0

Fwiw, finalmente decidió seguir a DISQLite junto con este "feo", hacker, solución:

  • hecho algunos cambios (no tan pequeña) para minimizar escrito al DB dentro de las discusiones tanto como sea posible (Dos inserciones de base de datos necesarios en cada hilo)

  • Cuando absolutamente tenía que escribir algo para DB mientras se trabaja dentro de las discusiones, tomé la consulta SQL parámetros & ellos escribió en una carpeta especial (escribir en archivos es muy rápido), es decir.

C: \ Mis proyectos \ pendientes-sql \ insert_SOME-GUID.txt

Cada archivo se vería así:

Param1 | Param2 | Param3 | param4 |

  • Una vez que he terminado con los hilos (o si mi aplicación se bloquea), me llamaron una rutina que exploró este carpeta, extrae los parámetros SQL y ejecutarlos mediante declaraciones preparadas (envuelto dentro de una transacción).

  • Cualquier archivo que contenga menos de, digamos, 4 parámetros se considerarán dañados y se saltearán.

Esta es una diablos de hacker fea algoritmo (que pena por mí!), Pero funciona, es rápido, es (casi) ACID, y no tener que pasar meses aprendiendo otra DB motor que puede (o no) ser adecuado.

Solo quería agradecer a todos por su ayuda, la presión del tiempo me impide cambiar a otro motor de DB, al menos para este proyecto.

0

Este es mi punto:

Absolute Database es una buena alternativa.

+0

¡Gracias! De hecho, cambié de Absolute a DISQLite el verano pasado (lo he usado durante 6 años). AFAIK, con AbsoluteDB, tiene soporte de escritura concurrente o ACIDity, pero no puede tener ambos – TheDude

+0

. De nada. ¿Qué versión por favor? – menjaraz

+0

Utilicé v5 y v6 (ambos para D2010 y D7) – TheDude

2

¿Sería algo así como la versión incorporada de Firebird DB ser de alguna ayuda?

FirbirdSQL.org Downloads Page

he utilizado esto con éxito en el pasado.

+0

De hecho, la versión 2.5 también es una buena opción – menjaraz

+0

Interesante ... FireFird definitivamente parece ser una buena opción. Lo investigaré (me pregunto cómo se compara en términos de velocidad con SQLite ...) – TheDude

+0

@Gdhami: he usado ambos y aunque la versión integrada de FB es un poco más pesada que SQLite, tiene todos los características de la versión completa de FB. Con la excepción de usuario único frente a usuarios múltiples, por supuesto. Una vez que el motor se carga en la memoria, esperaría que la diferencia de velocidad fuera mínima. –

1

Simplemente divida sus tablas (que podrían escribirse simultáneamente) en archivos de base de datos SQLite separados y attach todos juntos mediante su conexión principal.

+0

Gracias, sí, en realidad hice algo así (aunque no los adjunté: eso significaría perder ACIDity porque estoy usando WAL) ... sí * ayudó - mucho, pero mi perfilador dice algunos * * las consultas SQL ** muy simples tardan más de 20 segundos en ejecutarse en multi-threading, mientras que toma menos de 0.01 ms en modo de un solo hilo. (no es típico, pero sucede lo suficiente como para ralentizar toda la operación) – TheDude

+0

También debo mencionar que estoy usando consultas SQL simples con índices, etc ... – TheDude

+0

¿Estás seguro de que no estás haciendo algo mal? Una gran diferencia entre las mismas consultas es muy extraña e improbable. También otra solución sería dejar de usar WAL. – Linas

3

¿Cuál es su velocidad de aplicación si:

  • usa una sola conexión de base de datos para todas sus hilos;
  • Protege su acceso a la conexión de base de datos con una sección crítica global.

A continuación, puede probar nuestra Sqlite3 static binding que fue compilado sin exclusión mutua hilo:

#define SQLITE_THREADSAFE 2 
// assuming multi-thread safety is made by caller - in our framework, there is 
// only one thread using the database connection at the same time, but there could 
// be multiple database connection at the same time (previous was 0 could be unsafe) 
#define SQLITE_OMIT_SHARED_CACHE 1 
// no need of shared cache in a threadsafe calling model 

Utilizamos un modelo de este tipo en nuestro marco Mormot ORM, y, asociado con cuatro niveles de caché:

  • Memoria caché de declaraciones para la reutilización de sentencias de SQL y parámetros vinculados sobre la marcha;
  • caché de resultados global JSON en el nivel de la base de datos, que se vacía globalmente en cualquier INSERT/UPDATE;
  • Caché de registro sintonizado en el nivel CRUD/RESTful para tablas o registros especificados en el lado del servidor;
  • Caché de registro sintonizado en el nivel CRUD/RESTful para tablas o registros especificados en el lado del cliente.

El rendimiento resultante no es malo en absoluto: se adapta bien en el acceso de subprocesos múltiples, incluso con una sección crítica global. ¡Por supuesto, SQlite3 no fue diseñado para escalar tan bien como Oracle! Pero he usado SQlite en aplicaciones reales, con muchos clientes. Puede considerar usar FireBird que tiene una arquitectura más compleja (y ajustada) para el cliente-servidor.

Para hacer que escribir sea más rápido, puede agrupar sus escritos en una transacción, y será mucho más rápido. Esto es lo que uso for speed-up writing y puede ampliar este concepto con varios clientes: en el lado del servidor, reagrupa sus escrituras en una transacción compartida, que se comprometerá después de un período de tiempo de espera (por ejemplo, un segundo).

SQLite3 es muy rápido para agregar (incluso más con una instrucción INSERT preparada con parámetros enlazados), pero lento para adiciones individuales, porque tiene que bloquear todo el archivo con API de bajo nivel, lo cual es muy lento. Para que sea ACID, asegúrese de que la confirmación siempre se procese. De hecho, otros motores DB logran una buena velocidad concurrente con un proceso similar, oculto en el fondo. Se espera que el método de escritura predeterminado de SQLite3 sea tal, para garantizar el acceso al mismo archivo desde múltiples procesos, pero en su aplicación Cliente-Servidor, puede confiar en el hecho de que será el único en acceder al Archivo de base de datos SQLite3, por lo que será seguro.

+0

gracias, el rendimiento de lectura está bien con WAL, mi problema es en realidad con ** escritura concurrente **, que lamentablemente SQLite no admite :( – TheDude

+0

En cuanto al rendimiento de mi aplicación, es ** muy ** lento con un solo hilo .Intento usar secciones críticas solo donde sea necesario (una vez el comienzo y una vez al final de cada hilo, solo para escribir en el DB). ¡Muchas cosas buenas en tu publicación, lo investigaré, muchas gracias! – TheDude

+0

Para hacer que escribir sea más rápido, puede agrupar sus escritos en una transacción, luego será * mucho * más rápido. Esto es lo que uso en http://blog.synopse.info/post/2011/06/03/BATCH-sequences-for-adding/updating/deleting-records y puede ampliar este concepto con múltiples clientes: en el servidor De lado, usted reagrupa sus escrituras en una transacción compartida, que se comprometerá después de un período de tiempo de espera (por ejemplo, un segundo). SQLite3 es muy rápido para dicha adición (incluso más con una instrucción INSERT preparada con parámetros enlazados), pero lenta para adiciones individuales. Esto es lo que hacen otros DB de cliente-servidor. –

Cuestiones relacionadas