Django Table с миллионом строк

У меня есть проект с 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 миллионами строк?

Существует ли альтернативное решение?

Спасибо ^ __^

9
задан Srikar Appalaraju 29 November 2012 в 15:30
поделиться

5 ответов

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

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

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

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

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

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

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

12
ответ дан 4 December 2019 в 08:33
поделиться

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

Редактирование: И ради Бога, держите его в одной таблице и используйте индексы по мере необходимости.

10
ответ дан 4 December 2019 в 08:33
поделиться

Если вы используете Windows, можно просмотреть проводник процессов («procexp.exe» поставляется с средствами Sysinternals от Microsoft). В свойствах каждого процесса имеется вкладка «Потоки», в которой перечислены все потоки и их время ЦП.

Если это не дает достаточно информации, используйте механизмы профилирования Python, которые не слишком трудно использовать.

-121--4055880-

По какой-либо причине мои EmacsW32 по установке WinXP продолжали отправлять директивы browse-url в оболочку с "open file ://alone, и это не так хорошо работало *. Отрезание его у колен и изменение оригинального Джастина, как показано ниже, сработало для меня:

(defun open-in-browser()
"open buffer in browser, unless it is not a file. Then fail silently (ouch)."
  (interactive)
  (if (buffer-file-name)
      (let ((filename (buffer-file-name)))
        (shell-command (concat "start firefox.exe \"file://" filename "\"")))))

Нуждается в некотором улучшении. А также замена любимого браузера. d * * н ты, жесткий код.

* Я думаю, что проблема была в проверке системного типа в browse-url-default-windows-browser, но не положительной.

-121--1456882-

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

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

1
ответ дан 4 December 2019 в 08:33
поделиться

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

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

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

1
ответ дан 4 December 2019 в 08:33
поделиться

Я не знаком с Джанго, но у меня общее понимание БД.

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

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

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

0
ответ дан 4 December 2019 в 08:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: