Таблица Джанго с миллионами строк - PullRequest
9 голосов
/ 12 января 2010

У меня есть проект с 2 приложениями (книги и ридер).

В приложении Книги есть таблица с 4 миллионами строк с полями:

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

Чтобы не запрашивать базу данных с 4 миллионами строк, я думаю разделить ее по темам (20 моделей с 20 таблицами по 200 000 строк (book_horror, book_drammatic, ecc).

В приложении "читатель" я думаю вставить следующие поля:

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

Поэтому вместо ForeignKey я думаю использовать целое число «book_subject» (которое позволяет получить доступ к соответствующей таблице) и «book_id» (которое позволяет получить доступ к книге в таблице, указанной в «book_subject»).

Является ли хорошим решением избежать запроса таблицы с 4 миллионами строк?

Есть ли альтернативное решение?

Спасибо ^ __ ^

Ответы [ 6 ]

12 голосов
/ 12 января 2010

Как многие уже говорили, немного преждевременно разбивать вашу таблицу на более мелкие таблицы (горизонтальное разбиение или даже разбиение). Базы данных созданы для обработки таблиц такого размера, поэтому проблема с производительностью, вероятно, где-то еще.

Индексы - это первый шаг, похоже, вы это сделали. Для обработки БД с индексом должно быть 4 миллиона строк.

Во-вторых, проверьте количество запросов, которые вы выполняете. Вы можете сделать это с помощью чего-то вроде панели инструментов отладки django, и вы часто будете удивлены, как много ненужных запросов будет сделано.

Кэширование - это следующий шаг, используйте memcached для страниц или частей страниц, которые остаются неизменными для большинства пользователей. Здесь вы увидите самое большое повышение производительности при минимальных затратах.

Если вам действительно нужно разделить таблицы, последняя версия django (альфа-версия 1.2) может справиться с разделением (например, multi-db), и вы сможете написать решение для горизонтального разделения (postgres предлагает способ сделать это в db). Пожалуйста, не используйте жанр для разделения таблиц! выберите что-то, что вы никогда не будете менять, и что вы всегда будете знать при выполнении запроса. Как автор и разделить по первой букве фамилии или что-то. Это требует больших усилий и имеет ряд недостатков для базы данных, которая не особенно велика - вот почему большинство людей здесь советуют против этого!

[редактировать]

Я пропустил денормализацию! Поместите общее количество, суммы и т. Д. В таблицу, например, автора, чтобы предотвратить присоединения к общим запросам. Недостатком является то, что вы должны поддерживать его самостоятельно (пока django не добавит DenormalizedField). Я хотел бы взглянуть на это во время разработки для ясных, простых случаев или после того, как кеширование не помогло вам - но хорошо до разделения или горизонтального разбиения.

10 голосов
/ 12 января 2010

ForeignKey реализовано как IntegerField в базе данных, поэтому вы экономите мало или ничего за счет искажения вашей модели.

Edit: И, ради бога, держи его в одной таблице и используй соответствующие индексы.

1 голос
/ 05 марта 2012

Вы не упомянули, какую базу данных вы используете. Некоторые базы данных, такие как MySQL и PostgreSQL, имеют предельно консервативные настройки, которые в основном непригодны для всего, кроме крошечных баз данных на крошечных серверах.

Если вы сообщите нам, какую базу данных вы используете, и на каком оборудовании оно работает, и используется ли это оборудование совместно с другими приложениями (например, оно также обслуживает веб-приложение), то мы можем предоставить вам некоторые конкретные советы по настройке.

Например, в MySQL вам, вероятно, потребуется настроить параметры InnoDB; для PostgreSQL вам нужно изменить shared_buffers и ряд других настроек.

1 голос
/ 12 января 2010

Распространенным подходом к решению проблемы такого типа является Sharding . К сожалению, в основном это зависит от ORM (Hibernate делает это чудесно), и Django не поддерживает это. Тем не менее, я не уверен, что 4 миллиона строк действительно так плохо. Ваши запросы должны быть полностью управляемыми.

Возможно, вам стоит заняться кэшированием с помощью чего-то вроде memcached Django поддерживает это довольно хорошо.

1 голос
/ 12 января 2010

У вас проблемы с производительностью? Если это так, вам может понадобиться добавить несколько индексов .

Один из способов получить представление о том, в чем может помочь индекс, - просмотреть журнал запросов вашего db-сервера ( инструкции здесь , если вы используете MySQL).

Если у вас нет проблем с производительностью, просто продолжайте. Базы данных созданы для обработки миллионов записей, и django довольно хорошо генерирует разумные запросы.

0 голосов
/ 12 января 2010

Я не знаком с Django, но у меня есть общее представление о БД.

Если у вас большие базы данных, вполне нормально индексировать вашу базу данных . Таким образом, получение данных должно быть довольно быстрым.

Когда речь идет о том, чтобы связать книгу с читателем, вы должны создать другую таблицу, которая связывает читателя с книгами.

Неплохая идея разделить книги на предметы. Но я не уверен, что вы имеете в виду, имея 20 заявок.

...