Pregunta

He estado experimentando un problema de rendimiento con la eliminación de manchas en Derby, y se preguntaba si alguien podría ofrecer algún consejo.

Esto es principalmente con 10.4.2.0 bajo Windows y Solaris, aunque también he probado con la nueva versión candidata 10.5.1.1 (ya que tiene muchos cambios de línea de negocio), pero esto no hace ninguna diferencia significativa.

El problema es que con una tabla que contiene muchas de las grandes gotas, de la supresión de una sola fila puede llevar mucho tiempo (a menudo más de un minuto).

He reproducido esto con una pequeña prueba que crea una tabla, inserta un par de filas con manchas de diferentes tamaños, a continuación, los elimina.

El esquema de la tabla es sencillo, basta con:

crear BLOBTest mesa (entero Identificación del generada por defecto como identidad, b blob)

y luego he creado 7 filas con los siguientes tamaños: blob. 1024 bytes, 1 MB, 10 MB, 25Mb, 50Mb, 75 MB, 100 Mb

He leído las gotas hacia atrás, para comprobar que se haya creado correctamente y tienen el tamaño correcto.

A continuación, se han eliminado mediante la instrucción SQL ( “eliminar de BLOBTest donde id = X”).

Si elimino las filas en el orden en que los creé, los tiempos promedio para borrar una sola fila son:

1024 bytes: 19,5 segundos

1Mb: 16 segundos

10Mb: 18 segundos

25Mb: 15 segundos

50 MB: 17 segundos

75 MB: 10 segundos

100 Mb: 1,5 segundos

Si elimino en orden inverso, los tiempos promedio para eliminar una sola fila son:

100 Mb: 20 segundos

75 MB: 10 segundos

50 MB: 4 segundos

25Mb: 0,3 segundos

10Mb: 0,25 segundos

1Mb: 0,02 segundos

1024 bytes: 0.005 segundos

Si creo siete pequeñas manchas, eliminar tiempos son todos instantánea.

Así pues, parece que el tiempo de eliminación parece estar relacionada con el tamaño total de las filas de la tabla más que el tamaño de la mancha se quita.

Me he encontrado las pruebas de un par de veces, y los resultados parecen ser reproducible.

Así que, ¿alguien tiene alguna explicación para el rendimiento, y cualquier sugerencia sobre cómo evitar o arreglarlo? No hacer uso de grandes manchas bastante problemático en un entorno de producción ...

¿Fue útil?

Solución

Tengo exactamente el mismo problema que pueda tener.

He descubierto que cuando lo haga BORRAR, derby realidad "leyó" el archivo de gran segmento completo. Yo uso FileMon.exe observar cómo se ejecute.

Mi archivo de tamaño que 940MB, y se tarda 90 para eliminar sólo una única fila.

Creo que tienda derby los datos de la tabla en un solo archivo dentro. Y de alguna forma un error de diseño / implementación que hacer que se leyó todo en lugar de hacerlo con un índice adecuado.

Yo eliminar por lotes en lugar de solucionar este problema. Vuelvo a escribir una parte de mi programa. Era "donde id =?" en la auto-entrega. Entonces vuelvo a escribir muchas cosas y ahora "donde ID IN (?, .......?)" Encerrado en una transacción.

El tiempo total de reducir a 1/1000 entonces antes.

Sugiero que usted puede agregar una columna para "marcar como eliminado", con un horario que hacer lotes eliminación real.

Otros consejos

Por lo que yo puedo decir, Derby hará sólo BLOB tienda en línea con el resto de datos de bases de datos, por lo que terminan con el BLOB se separó más de una tonelada de archivos de páginas separadas DB. Este mecanismo de almacenamiento BLOB es bueno para ACID, y bueno para los BLOB más pequeñas (por ejemplo, miniaturas de imágenes), pero se rompe con objetos más grandes. De acuerdo con la documentación de Derby, girando confirmación automática cuando BLOB manipulación también pueden mejorar el rendimiento , pero esto sólo se van tan lejos.

sugieren fuertemente que migre a H2 o otro DBMS si bien el rendimiento en grandes BLOB es importante , y los BLOB deben permanecer dentro de la base de datos. Usted puede utilizar el cliente SQL SQuirreL y su complemento DBCopy migrar directamente entre DBMSes (sólo tiene que indicar al conductor Derby / JavaDB JDBC y el conductor H2). Yo estaría encantado de ayudar con esta parte, ya que sólo lo hice yo, y no he sido más feliz.

En su defecto, puede mover los BLOB de la base de datos y en el sistema de archivos. Para ello, debería reemplazar la columna BLOB en la base de datos con un tamaño de BLOB (si se desea) y la ubicación (un URI o cadena archivo dependiente de la plataforma). Al crear una nueva burbuja, se crea un archivo correspondiente en el sistema de archivos. La ubicación podría basarse fuera de un directorio dado, con la clave primaria anexa. Por ejemplo, su base de datos está en "DBFolder / DBName" y sus gotas ir en "DBFolder / DBName / Blob" y tienen nombre de archivo "BLOB_PRIMARYKEY.bin" o algo por el estilo. Para editar o leer las gotas, se consulta la base de datos para la ubicación, y luego hacer leer / escribir en el archivo directamente. A continuación se conecte el nuevo tamaño del archivo a la base de datos si ha cambiado.

Estoy seguro de que esta no es la respuesta que desea, pero para un entorno de producción con los requisitos de rendimiento no me usar Java DB. MySQL es tan libre y manejará sus necesidades mucho mejor. Creo que verdaderamente justo para superar su cabeza contra una limitación de la solución que ha elegido.

Yo por lo general sólo uso Derby como un caso de prueba, y especialmente cuando toda mi DB puede caber fácilmente en la memoria. Tu caso es distinto.

¿Ha tratado aumentar el tamaño de página de la base de datos

No hay información sobre esto y más en el manual del de sintonización de Java DB que pueden serle de utilidad.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top