2010-01-12 19 views
9

Tengo un proyecto con 2 aplicaciones (libros y lector).Django Tabla con millones de filas

aplicación

Libros tiene una mesa con 4 milions de filas con estas casillas:

book_title = models.CharField(max_length=40) 
book_description = models.CharField(max_length=400) 

Para evitar para consultar la base de datos con 4 milions de filas, estoy pensando que dividirlo por tema (20 modelos con 20 . tablas con 200.000 filas (book_horror, book_drammatic, ECC)

En "lector" de aplicaciones, pienso para insertar estas casillas:

reader_name = models.CharField(max_length=20, blank=True) 
book_subject = models.IntegerField() 
book_id = models.IntegerField() 

así que en vez de Comercio exterior nKey, estoy pensando en usar un entero "book_subject" (que permite acceder a la tabla apropiada) y "book_id" (que permite acceder al libro en la tabla especificada en "book_subject").

¿Es una buena solución para evitar consultar una tabla con 4 millones de filas?

¿Existe una solución alternativa?

Gracias^__^

+8

4 millones no es mucho, tiene un caso de optimización prematura. – Tobu

+0

La tabla se consulta desde ajax usando un campo de autocompletar con este consulta en el views.py: books.objects.filter (book_title__istartswith = request.GET [ 'q']) [100] – xRobot

+0

Si está consultando una tabla en un campo de texto y el rendimiento es el problema, puede optar por implementar la búsqueda de texto completo. Sin embargo, el tamaño de tu campo consultado es de solo 40 caracteres, y no estoy seguro de si representa un gran problema para la base de datos. – shanyu

Respuesta

12

Como muchos han dicho, es un poco prematuro dividir la tabla en tablas más pequeñas (partición horizontal o incluso fragmentación). Las bases de datos están diseñadas para manejar tablas de este tamaño, por lo que su problema de rendimiento probablemente sea en otro lugar.

Los índices son el primer paso, aunque parece que ya has hecho esto. 4 millones de filas deberían estar bien para que la base de datos maneje con un índice.

En segundo lugar, verifique la cantidad de consultas que está ejecutando. Puede hacer esto con algo así como la barra de herramientas de depuración django, y con frecuencia se sorprenderá de cuántas consultas innecesarias se están realizando.

El almacenamiento en caché es el siguiente paso, use memcached para páginas o partes de páginas que no se modifican para la mayoría de los usuarios. Aquí es donde verá su mayor impulso de rendimiento por el poco esfuerzo requerido.

Si realmente necesita dividir las tablas, la última versión de django (1.2 alpha) puede manejar sharding (por ejemplo, multi-db), y debería poder escribir a mano una solución de particionado horizontal (postgres ofrece una forma in-db de hacer esto). ¡Por favor, no use el género para dividir las tablas! elige algo que nunca, nunca cambiarás y que siempre sabrás cuando hagas una consulta. Como autor y divídalo por la primera letra del apellido o algo así. Esto es un gran esfuerzo y tiene una serie de inconvenientes para una base de datos que no es particularmente grande, ¡esta es la razón por la que la mayoría de la gente aquí está desaconsejando!

[editar]

omití desnormalización! Pon los recuentos, sumas, etc. comunes en la tabla eg author para evitar uniones en las consultas comunes. La desventaja es que debes mantenerlo tú mismo (hasta que django agregue un Campo Denormalizado). Me gustaría ver esto durante el desarrollo para casos claros y sencillos o después de que el almacenamiento en caché le haya fallado --- pero y antes de fragmentar o particionar horizontalmente.

+0

bien si voy a dividir la tabla, voy a dividirlo por la primera letra ... de hecho es más razonable :) La tabla se consulta desde ajax usando un campo de autocompletar con este consulta en el views.py: libros .objects.filter (book_title__istartswith = request.GET ['q']) [: 100] ¿Me recomiendas index + memcached? Gracias – xRobot

+0

Haga un índice en las primeras tres letras de título (o lo que sea que sea el primer número que comience a consultar la base de datos) y se ejecutará bastante rápido. – naivists

10

ForeignKey se implementa como IntegerField en la base de datos, por lo que ahorran poco o nada a costa de paralizar su modelo.

Edit: Y por el bien de todos, guárdelo en una tabla y use los índices según corresponda.

+0

Uso el índice pero la tabla tiene 4 millones de filas y a menudo se consulta. Así que no sé si el índice es suficiente: - \ – xRobot

+0

Si no es así, la base de datos necesita más memoria. –

+2

4 millones de filas no es para estornudar, pero las bases de datos están diseñadas para este tipo de cosas, especialmente si está indexando.Solo me preocuparía si consigues hasta al menos cien millones de filas. – LeafStorm

0

No estoy familiarizado con Django, pero tengo una comprensión general de DB.

Cuando tiene bases de datos grandes, es bastante normal que index your database. De esa manera, recuperar datos, debe ser bastante rápido.

Cuando se trata de asociar un libro con un lector, debe crear otra tabla que vincule el lector con los libros.

No es una mala idea dividir los libros en temas. Pero no estoy seguro de lo que quiere decir con 20 solicitudes.

+0

20 aplicaciones significa 20 tablas :) \t Uso ya el índice, pero la tabla tiene 4 millones de filas y a menudo se consulta. Así que no sé si el índice es suficiente: - \ – xRobot

+1

¡Dioses no! ¡No lo dividas en 20 tablas! Haga un diagrama EAR de sus tablas, y verá qué tabla adicional necesita para manejar esto. P.ej. tablas adicionales para relacionar a la persona con los libros, la categoría con los libros, etc. – Steven

0

¿Estás teniendo problemas de rendimiento? Si es así, puede necesitar add a few indexes.

Una forma de hacerse una idea de dónde ayudaría un índice es mirando el registro de consultas del servidor de DNS (instructions here si está en MySQL).

Si no está teniendo problemas de rendimiento, simplemente siga con ello. Las bases de datos están hechas para manejar millones de registros, y django es bastante bueno generando consultas sensatas.

+0

Sí, es un problema de rendimiento. Estoy usando el índice, pero la tabla tiene 4 millones de filas y a menudo se consulta. Así que no sé si el índice es suficiente: - \ – xRobot

+0

Es probable que un índice más grande (más columnas) sea el camino a seguir, tal vez además de memcached como @jcm mentions. A menudo, los índices de una sola columna no ayudan porque sus consultas no los utilizan. – Seth

0

Un enfoque común para este tipo de problema es Sharding. Desafortunadamente, depende en gran medida del ORM implementarlo (Hibernate lo hace maravillosamente) y Django no lo admite. Sin embargo, no estoy seguro de 4 millones de filas realmente es tan malo. Sus consultas deberían ser completamente manejables.

Quizás deba buscar en el almacenamiento en caché algo así como memcached. Django supports this bastante bien.

1

No ha mencionado qué base de datos está utilizando. Algunas bases de datos, como MySQL y PostgreSQL, tienen configuraciones extremadamente conservadas listas para usar, que básicamente no se pueden usar para nada, excepto para las bases de datos diminutas en servidores pequeños.

Si nos dices qué base de datos estás utilizando, y en qué hardware se está ejecutando, y si ese hardware se comparte con otras aplicaciones (si también está sirviendo a la aplicación web, por ejemplo) entonces podremos dar usted algunos consejos específicos de ajuste.

Por ejemplo, con MySQL, es probable que deba ajustar la configuración de InnoDB; para PostgreSQL, deberá modificar shared_buffers y una serie de otras configuraciones.

Cuestiones relacionadas