SQL Разделение больших полей для ускорения запросов - PullRequest
0 голосов
/ 23 мая 2018

Допустим, у меня есть таблица BOOK:

BOOK_ID INT(6) PK
--------------------
FILE_EXTENSION VARCHAR(5)
TITLE VARCHAR(60)
LANGUAGE VARCHAR(10)
EDITION INT(2)
PUBLISHMENT_OFFICE_ID INT(4)
PUBLISH_YEAR INT(4)
RATING INT(1)
FILE_UPDOAD_DATE DATE
LINK VARCHAR(150)

Эта таблица предназначена для использования как для поиска книг (например, по расширению, издательскому бюро, по авторам (из других таблиц),и т. д.) и для полной визуализации (напечатайте на странице все книги со всеми этими полями).

Поэтому возникает вопрос: например, если я сделаю

SELECT BOOK_ID FROM BOOK WHERE FILE_EXTENSION = 'PDF'

, это приведет к загрузкевсех больших полей (ссылка, заголовок и, возможно, запланированный большой двоичный объект) в качестве промежуточного результата, или он отбросит все ненужные поля, как только предложение WHERE будет переведено без проблем с производительностью?

Вопрос приводит к решению:отдельные большие поля в другой таблице с тем же PK, чтобы замедлить визуализацию (потому что требуется JOIN), но чтобы ускорить поиск?Стоит ли это?

PS Эта конкретная БД не предназначена для хранения большого количества данных, поэтому мои запросы (я надеюсь) не будут такими медленными.Но этот вопрос касается общего дизайна баз данных (скажем, 10 ^ 8 записей).

PPS Pls не связывает меня с нормализацией базы данных (моя полная БД хорошо нормирована)

Ответы [ 2 ]

0 голосов
/ 29 мая 2018

"Столбцы хранятся как часть их строки."-- И да и нет.Все «маленькие» столбцы хранятся вместе в строке.Но TEXT и BLOB, когда они «большие», хранятся в другом месте.(Предполагается, что ENGINE=InnoDB.)

SELECT book_id FROM ... WHERE ext = 'PDF' выиграет от INDEX(ext, book_id).Без этого запрос обязательно сканирует всю таблицу (100 миллионов строк?).С этим индексом это будет очень эффективно.

«печатать на странице все книги со всеми этими полями» - предположительно это исключает громоздкие столбцы?В этом случае SELECT book_id против SELECT all-these-fields будет стоить примерно столько же.Это разумно сделать на веб-странице - , если , вы не пытаетесь отобразить тысячи книг на одной странице.Это становится проблемой «плохого пользовательского интерфейса», а не проблемой «неэффективного запроса».

title и link, вероятно, подпадают под заголовок «маленький» в моем обсуждении выше.Но любой BLOBs, скорее всего, будет «большим».

Да, можно сделать «вертикальное разбиение», чтобы разбить большие элементы, но это в основном повторяет то, чтоInnoDB уже делает.Не беспокойтесь.

100M рядов находятся на арене, где мы должны обсудить эти вещи.Мои комментарии пока касаются только поверхности.Чтобы копнуть глубже, нам нужно увидеть реальную схему и некоторые важные запросы.Я ожидаю, что некоторые запросы будут медленными.При наличии 100 миллионов строк улучшение одного запроса иногда вредит другому.

0 голосов
/ 23 мая 2018

Столбцы хранятся как часть их строки.Строки хранятся как часть страницы.Если вам нужен один столбец из одной строки, вам нужно прочитать всю строку, фактически вы читаете всю страницу, в которой находится эта строка. Это могут быть тысячи строк, включая все их столбцы.Надеемся, что на этой странице есть и другие интересующие вас строки, и чтение не теряется.

Именно поэтому базы данных Columnar становятся настолько популярными для аналитики.Они хранят столбцы отдельно.Они по-прежнему хранят значения в страницах.Таким образом, вы читаете тысячи строк с диска для этого столбца, но в аналитике вас, вероятно, заинтересуют все или большинство этих строк.Таким образом, вы можете иметь сотни столбцов, но только когда-либо читаете запрашиваемые столбцы.

MySQL не имеет ColumnStore.Итак, вам нужна альтернатива.

Во-первых, большие поля должны находиться в отдельной таблице, на которую вы уже ссылались.

Во-вторых, вы можете использовать индекс покрытия.

Если вы индексируете (file_extension, book_id), запрос SELECT book_id FROM book WHERE file_extension = 'pdf' может быть удовлетворен, просто читая индекс.Ему никогда не нужно читать саму таблицу. (индексы по-прежнему хранятся в виде страниц на диске, но только столбцы, к которым относится индекс, и, возможно, указатель строки. Гораздо уже, чем таблица.)

Хотя это немного неуклюжепотому что индекс покрытия должен охватывать интересующие вас столбцы.

На практике ваши поля достаточно малы, чтобы не требовать этого внимания, пока это не станет проблемой.Было бы разумно хранить BLOB s в отдельной таблице.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...