Может ли MySQL разумно выполнять запросы на миллиарды строк?


283

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

Формат ввода

Каждый входной файл содержит один прогон спектрометра; каждый прогон состоит из набора сканов, и у каждого скана есть упорядоченный массив точек данных. Существует немного метаданных, но большая часть файла состоит из 32- или 64-битных массивов или чисел с плавающей запятой.

Хост-система

| ---------------- + ------------------------------- |
| ОС | Windows 2008 64-разрядная |
| Версия MySQL | 5.5.24 (x86_64) |
| Процессор | 2x Xeon E5420 (всего 8 ядер) |
| RAM | 8 Гб |
| Файловая система SSD | 500 ГиБ |
| HDD RAID | 12 TiB |
| ---------------- + ------------------------------- |

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

Файловая статистика

| ------------------ + -------------- |
| количество файлов | ~ 16 000 |
| общий размер | 1,3 TiB |
| минимальный размер | 0 байт |
| максимальный размер | 12 ГиБ |
| значит | 800 МиБ |
| средний | 500 МиБ |
| общее количество данных | ~ 200 миллиардов |
| ------------------ + -------------- |

Общее количество точек данных является очень приблизительной оценкой.

Предлагаемая схема

Я планирую делать вещи "правильно" (то есть нормализовать данные как сумасшедшие) и поэтому буду иметь runsтаблицу, spectraтаблицу с внешним ключом runsи datapointsтаблицу с внешним ключом для spectra.

Вопрос о 200-миллиардном назначении данных

Я собираюсь проанализировать несколько спектров и, возможно, даже несколько прогонов, что приведет к запросам, которые могут касаться миллионов строк. Предполагая, что я все правильно проиндексировал (что является темой для другого вопроса) и не пытаюсь перетасовать сотни МБ по сети, возможно ли удаленное управление MySQL для этого?

Дополнительная информация

Данные сканирования будут поступать из файлов в формате mzML на основе XML . Мясо этого формата находится в <binaryDataArrayList>элементах, где хранятся данные. Каждое сканирование создает> = 2 <binaryDataArray>элемента, которые вместе взятые образуют двумерный (или более) массив формы [[123.456, 234.567, ...], ...].

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

Мой наивный план для схемы базы данных:

runs Таблица

| имя столбца | тип |
| ------------- + ------------- |
| id | ПЕРВИЧНЫЙ КЛЮЧ |
| время начала | TIMESTAMP |
| имя | VARCHAR |
| ------------- + ------------- |

spectra Таблица

| имя столбца | тип |
| ---------------- + ------------- |
| id | ПЕРВИЧНЫЙ КЛЮЧ |
| имя | VARCHAR |
| индекс | INT |
| тип_спектра | INT |
| представительство | INT |
| run_id | ИНОСТРАННЫЙ КЛЮЧ |
| ---------------- + ------------- |

datapoints Таблица

| имя столбца | тип |
| ------------- + ------------- |
| id | ПЕРВИЧНЫЙ КЛЮЧ |
| spectrum_id | ИНОСТРАННЫЙ КЛЮЧ |
| мз | ДВОЙНОЙ |
| num_counts | ДВОЙНОЙ |
| индекс | INT |
| ------------- + ------------- |

Это разумно?


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

Вот график одного спектра (сканирования) того типа данных, с которыми я буду иметь дело:

Скриншот просмотра

Цель программного обеспечения - выяснить, где и насколько значительны пики. Мы используем пакет проприетарного программного обеспечения, чтобы понять это сейчас, но мы хотим написать нашу собственную программу анализа (на R), чтобы мы знали, что, черт возьми, происходит под листами. Как видите, подавляющее большинство данных неинтересны, но мы не хотим выбрасывать потенциально полезные данные, которые пропустил наш алгоритм. Как только у нас будет список возможных пиков, которыми мы удовлетворены, остальная часть конвейера будет использовать этот пиковый список, а не необработанный список точек данных. Я полагаю, что было бы достаточно сохранить необработанные точки данных в виде большого двоичного объекта, чтобы при необходимости их можно было повторно проанализировать, но сохранить только пики в качестве отдельных записей базы данных. В этом случае будет только пара дюжин пиков в спектре, так что безумное масштабирование не должно



8
Поскольку это необработанные данные масс-спектрометра для аналого-цифрового опроса, кажется, действительно глупо хранить их в базе данных. Я бы взял свои необработанные данные, выгрузил их, обработал и сохранил обработанные РЕЗУЛЬТАТЫ в базе данных. Результатами будут (а) формы волны, сохраненные по одной форме волны на строку, (b) другие данные, связанные с этими формами сигнала, такие как калибровочные кривые, и (с) строки результатов в базе данных. Это отрежет миллиарды строк раздува от вашего дизайна. Когда вы захотите повторно запустить первоначальный анализ, вы фактически отредактируете некоторые параметры, запустите гигантскую вычислительную операцию и сохраните новые результаты в БД.
Уоррен П

Ответы:


115

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

Как правило, хранить двоичные данные в базах данных в большинстве случаев неправильно. Обычно есть лучший способ решения проблемы. Хотя хранение двоичных данных в реляционной базе данных по своей сути не является неправильным, зачастую недостатки перевешивают выгоды. Реляционные базы данных, как следует из названия, лучше всего подходят для хранения реляционных данных. Двоичные данные не являются реляционными. Это увеличивает размер (часто значительно) базы данных, может снизить производительность и может привести к возникновению вопросов о поддержке экземпляров MySQL с миллиардами записей. Хорошей новостью является то, что есть базы данных, особенно хорошо подходящие для хранения двоичных данных. Одной из них, хотя и не всегда очевидной, является ваша файловая система! Просто придумайте структуру каталогов и имен файлов для ваших двоичных файлов,

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


5
Почему считается неправильным хранить двоичные данные в базе данных? (Частично спрашиваю, потому что мне любопытно, а также потому, что я могу придумать вариант использования для него.)

15
Если двоичные данные не имеют значения по отдельности, они не должны храниться как уникальная строка. Пиксель 500x325 на изображении не имеет значения.

1
Это очень хороший момент. Вероятно, нам следует хранить необработанные файлы на случай, если нам понадобится извлечь что-то еще позже, но аналогия с хранением изображений - отличная. Нам никогда не понадобится доступ к каждому объекту данных (если только мы не переделываем пиковое извлечение), поэтому простое хранение извлеченной статистической информации было бы намного лучше.
Хэксни

107

Однажды я работал с очень большой (Terabyte +) базой данных MySQL. Самая большая таблица у нас была буквально более миллиарда строк. Это было с использованием MySQL 5.0, поэтому возможно, что все могло улучшиться.

Это сработало. MySQL большую часть времени правильно обрабатывал данные. Это было чрезвычайно громоздко, хотя. (Если вам нужна доступность на уровне шести сигма с терабайтом данных, не используйте MySQL. Мы были стартапом, у которого не было БД и ограниченных средств.)

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

У нас было множество таблиц в диапазоне от 10 до 100 миллионов. Любые значительные присоединения к таблицам были слишком трудоемкими и заняли бы вечность. Поэтому мы написали хранимые процедуры для «обхода» таблиц и объединения процессов с диапазонами идентификаторов. Таким образом, мы будем обрабатывать данные по 10-100 000 строк за раз (объединение с идентификаторами 1-100 000, затем 100 001-200 000 и т. Д.). Это было значительно быстрее, чем объединение против всей таблицы.

Использование индексов для очень больших таблиц, которые не основаны на первичном ключе, также намного сложнее. Mysql 5.0 хранит индексы в двух частях - он хранит индексы (кроме первичного индекса) как индексы для значений первичного ключа. Таким образом, индексированный поиск выполняется в двух частях: сначала MySQL переходит к индексу и извлекает из него значения первичного ключа, которые ему нужно найти, затем выполняет второй поиск по индексу первичного ключа, чтобы найти, где находятся эти значения.

Суть в том, что для очень больших таблиц (1-200 миллионов плюс строки) индексация по таблицам является более строгой. Вам нужно меньше, более простых индексов. И выполнение даже простых операторов выбора, которые не находятся непосредственно в индексе, может никогда не вернуться. Где пункты должны попасть в индексы или забыть об этом.

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

Попытка выполнить анализ на 200 миллиардах строк данных потребует очень высокотехнологичного оборудования, а также большого количества ручного труда и терпения. Сохранение резервных копий данных в формате, который вы можете восстановить, было бы важной задачей.

Я согласен с ответом srini.venigalla, что нормализация данных как сумасшедших не может быть хорошей идеей здесь. Объединение нескольких таблиц с таким большим количеством данных откроет вам риск сортировки файлов, что может означать, что некоторые ваши запросы просто никогда не вернутся. Денормализация с помощью простых целочисленных клавиш даст вам больше шансов на успех.

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


1
MySQL значительно улучшился в отделе индексов (...) с 5.0. Было бы интересно посмотреть, как оно себя ведет сейчас.
Кольцо Ø

70

нормализуя данные как сумасшедшие

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

Is this reasonable?

Я также создал бы дополнительную плоскую таблицу со всеми данными.

run_id | spectrum_id | data_id | <data table columns..> |

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

Стратегия заключается в том, чтобы сначала выполнить запрос к приведенной выше таблице, выгрузить результаты во временную таблицу и соединить временную таблицу с таблицами поиска Run и Spectrum и получить нужные данные.


Вы проанализировали свои потребности в записи и потребности в чтении? Будет очень заманчиво отказаться от SQL и перейти к нестандартным механизмам хранения данных. На мой взгляд, это должно быть последним средством.

Чтобы ускорить скорость записи, вы можете попробовать метод Socket Handler. Percona, если я помню, упаковывает Handler Socket в свой установочный пакет. (никакого отношения к Перконе!)

http://yoshinorimatsunobu.blogspot.com/2010/10/using-mysql-as-nosql-story-for.html


33

Краткий ответ - полное «да» - с ростом числа строк возрастает важность выбранной схемы, типов данных и операций, которые вы выбираете.

Степень нормализации ваших данных зависит от операций, которые вы планируете выполнять с сохраненными данными. Ваша таблица «точек данных», в частности, кажется проблематичной - планируете ли вы сравнивать n-ую точку из любого данного спектра с m-й из любого другого? Если нет, хранить их отдельно может быть ошибкой. Если ваши точки данных не являются самостоятельными, но имеют смысл только в контексте связанных с ними спектров, вам не нужен ПЕРВИЧНЫЙ КЛЮЧ - внешнего ключа к спектрам и столбца 'n' (ваш столбец 'index'?) Будет достаточно ,

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

Самый большой MySQL, которым я когда-либо лично управлял, составлял ~ 100 миллионов строк. При таком размере вы хотите сохранить ваши строки и, следовательно, ваши поля фиксированного размера - это позволяет MySQL эффективно рассчитывать положение любой строки в таблице путем умножения на фиксированный размер каждой строки (подумайте о арифметике указателя) - хотя точные детали зависят от того, какой механизм хранения вы планируете использовать. Используйте MyISAM, если вам это сойдет с рук, ему недостает надежности, он компенсирует скорость, и в вашей ситуации этого должно быть достаточно. Замените поля переменного размера, такие как VARCHAR, на CHAR (n) и используйте RTRIM () в ваших запросах на чтение.

Как только строки вашей таблицы имеют фиксированную ширину, вы можете уменьшить количество байтов, тщательно оценив целочисленные типы данных MySQL (некоторые из которых нестандартны). Каждую 1-байтовую экономию, которую вы можете извлечь, преобразовав 4-байтовый INT в 3-байтовый MEDIUMINT, вы сэкономите ~ 1 МБ на миллион строк - это означает меньший объем дискового ввода-вывода и более эффективное кэширование. Используйте наименьшие возможные типы данных, которые вы можете избежать . Тщательно оцените типы с плавающей запятой и посмотрите, сможете ли вы заменить 8-байтовые DOUBLE на 4-байтовые FLOAT или даже <8-байтовые NUMERIC с фиксированной точкой . Запустите тесты, чтобы убедиться, что все, что вы выберете, не укусит вас позже.

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

Самое главное, что бы вы ни делали, не думайте, что вы выбрали идеальную схему, а затем вслепую начинаете помещать десятки миллионов записей. Хорошие проекты требуют времени для развития. Создайте большой, но управляемый (скажем, 1-5%) набор тестовых данных и проверьте правильность и производительность вашей схемы. Посмотрите, как выполняются различные операции (http://dev.mysql.com/doc/refman/5.0/en/using-explain.html) и убедитесь, что вы уравновешиваете свою схему в пользу наиболее частых операций.

Я сказал коротко? Упс. В любом случае, удачи!


23

Казалось бы, единственная причина для удаления данных точек данных из XML (в отличие от метаданных, таких как время и тип прогона) и в форму базы данных, - это когда вы анализируете спектры по массивам - то есть, возможно, находите все работает с определенной подписью. Только вы знаете свою проблемную область прямо сейчас, но это может быть похоже на хранение музыки, сэмплированной с частотой 96 кГц, с 1 сэмплом на строку. Я не уверен, что размер - это проблема больше, чем то, как используются данные. Опрос по данным будет эквивалентен запросу относительной амплитуды 2 минуты в песне для всех песен The Beatles. Если вы знаете, какие виды анализа могут быть выполнены, вполне возможно, что выполнение этих сигналов и сохранение их в метаданных о выполнении может иметь больше смысла.

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

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


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


18

Я запустил сервис веб-аналитики с примерно 50 серверами баз данных, каждый из которых содержит множество таблиц с числом строк более 100 миллионов, а несколько из них имеют размер более миллиарда строк, иногда до двух миллиардов (на каждом сервере).

Производительность здесь в порядке. Это очень нормализованные данные. Тем не менее, моя основная проблема при чтении этого заключается в том, что вы будете иметь более 4,2 миллиарда строк для этих таблиц (возможно, не "работает", а, вероятно, две другие), что означает, что вам нужно использовать BIGINT вместо INT для первичные / внешние ключи.

Производительность MySQL с полями BIGINT в индексированном столбце смехотворно ужасна по сравнению с INT. Я сделал ошибку, сделав это однажды с таблицей, которая, как мне казалось, могла бы вырасти до такого размера, и как только она достигла нескольких сотен миллионов строк, производительность была просто ужасной. У меня нет сырых цифр, но когда я говорю плохо, я имею в виду Windows ME плохо.

Этот столбец был первичным ключом. Мы превратили его обратно в INT и presto magico, производительность снова была хорошей.

Все наши серверы в то время были на Debian 5 и MySQL 5.0. С тех пор мы обновились до Debian 6 и Percona MySQL 5.5, поэтому с тех пор ситуация могла улучшиться. Но исходя из моего опыта здесь, нет, я не думаю, что это будет работать очень хорошо.


17

Работает это или нет, вы всегда столкнетесь с одной и той же проблемой на одном монолитном носителе: диски работают медленно. При скорости 100 МБ / с (довольно хорошо для вращающихся носителей) требуется всего 3 часа, чтобы прочитать таблицу объемом 1 ТБ; это предполагает, что никакой анализ или поиск или другие задержки не замедляют вас.

Вот почему почти каждая установка «больших данных» использует своего рода распределенное хранилище данных. Вы можете потратить в 8 раз больше денег на создание одного суперкомпьютерного компьютера для работы с вашей БД, но если у вас есть много данных, которые можно сканировать параллельно, вам почти всегда лучше распределить нагрузку на 8 более дешевых компьютеров.

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


13

Хм ... Я вижу только две причины, по которым вы выбрали бы такую ​​структуру данных:

  • вам действительно нужно делать любые datapoint против любых запросов datapoint
  • вы намерены выполнить всю свою логику в SQL

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

PS: Имейте в виду, что вам потребуется не менее 36 + 5 байт на точку данных, поэтому с точками данных 200B, которые должны предоставить вам как минимум 8,2 ТБ необходимого пространства.

PPS: Вам не нужен idстолбец в datapointsтаблице, PRIMARY KEY (spectrum_id, index)вероятно, достаточно (просто остерегайтесь, что это indexможет быть зарезервированное слово)


12

РЕДАКТИРОВАТЬ:

НЕ ДЕЛАЙТЕ ЭТОГО НА MYSQL С ДАННЫМИ, ХРАНЕННЫМИ НА ОДНОМ ДИСКЕ. Просто чтение этого количества данных с одного носителя займет часы. Вы должны масштабировать, а не вверх.

И вам нужно денормализовать ваши данные, если вы хотите провести эффективный анализ данных. Вы не проектируете онлайн систему здесь. Вы хотите сократить числа, дизайн соответственно.

Оригинальный ответ ниже строки.


Ответ будет варьироваться в зависимости от ваших запросов, MySQL, возможно, не лучший инструмент для этой работы. Возможно, вы захотите взглянуть на решение, которое вы можете масштабировать, а не увеличивать. Если вы готовы приложить некоторые усилия, возможно, вам стоит поискать решение Map Reduce, такое как Hadoop.

Если вы хотите выполнять больше специальных запросов , решение Google BigQuery может вам подойти. Соответствующая презентация от Google I / O 2012: сжатие больших данных с помощью BigQuery

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


9

Никто не упомянул, таким образом, мое предложение. Взгляните на массивные решения MySQL . Например, посмотрите эту высоко оцененную презентацию Tumblr .

Концепция заключается в следующем:

  • Вместо одной очень большой базы данных
  • Используйте много маленьких, содержащих части исходных данных

Таким образом, вы можете масштабировать горизонтально, вместо того, чтобы пытаться улучшить вертикальную производительность. Google BigTable и GFS также используют дешевые горизонтально масштабируемые узлы для хранения и запроса петабайт данных.

Однако могут возникнуть проблемы, если вам нужно будет выполнять запросы к разным шардам.


Если кому-то интересно, я подал заявку на расшаривание hello-world некоторое время назад. Это обсуждено здесь в сообщении в блоге. Я использовал RavenDB и C #, но детали не имеют значения, и идея та же самая.


7

На каком компьютере будут храниться данные? Это устройства с общим хранилищем?

Конечным фактором, который будет определять время вашего запроса, будут ваши жесткие диски. Базы данных и их оптимизаторы запросов предназначены для максимально возможного уменьшения количества дисковых операций ввода-вывода. Учитывая, что у вас есть только 3 таблицы, это будет сделано довольно надежно.

Скорости чтения / записи жесткого диска будут в 200-300 раз ниже, чем скорости памяти. Ищите жесткие диски с очень высокой задержкой и высокой скоростью чтения и записи. Если все эти данные находятся на одном диске объемом 2 ТБ, вы, вероятно, будете долго ждать завершения запросов. Задержка жесткого диска составляет ~ 10-15 миллисекунд, в то время как задержка памяти составляет менее 10 наносекунд. Задержка жесткого диска может быть в 1000-2000 раз медленнее, чем задержка памяти. Перемещение механического рычага на жестком диске является самой медленной вещью во всей этой системе.

Сколько у вас оперативной памяти? 16 гигабайт? Допустим, это позволяет хранить 32 записи. У вас есть 16000 файлов. Если вы собираетесь линейно сканировать все точки данных, вы можете легко получить 5-10 секунд в одиночку. Тогда фактор скорости передачи 50мб / с? Около 7 часов. Кроме того, любые временно сохраненные данные должны храниться на жестком диске, чтобы освободить место для чтения новых данных.

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

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

Оптимизация запроса может смотреть только на 1 запрос за один раз. Поэтому вложенные операторы выбора не могут быть оптимизированы. ОДНАКО, если вы знаете, что конкретный вложенный запрос приведет к возвращению небольшого набора данных, сохраните его. Оптимизация запроса использует гистограммы и грубые предположения, если вы знаете что-то о данных и запросе, тогда продолжайте и сделайте это.

Чем больше вы знаете о том, как ваши данные хранятся на диске, тем быстрее вы сможете писать свои запросы. Если все было сохранено последовательно в первичном ключе, может быть полезно отсортировать первичные ключи, возвращенные из вложенного запроса. Кроме того, если вы можете уменьшить набор наборов данных, которые нужно предварительно проанализировать, сделайте это. В зависимости от вашей системы, вы смотрите около 1 секунды передачи данных на файл.

Если вы собираетесь изменить значения Name (varchars), я бы изменил его на тип данных с максимальным размером, это предотвратит фрагментацию, а компромисс - это всего лишь несколько байтов памяти. Может быть, NVARCHAR с максимумом 100.

Что касается комментариев о денормализации таблицы. Я думаю, что может быть лучше просто сохранить точки данных в больших группах (возможно, в виде спектров), а затем выполнить анализ данных на python или языке, который взаимодействует с базой данных. Если только вы не мастер SQL.


3
Вы подчеркиваете огромную разницу между жестким диском и задержкой памяти, но ваши значения не совпадают с коэффициентом 1000. Если задержка жестких дисков составляет около 10 мс, а памяти 10 нс, задержки не будут различаться с коэффициентом 1000, но с коэффициентом 1000000!
spectre256

6

Для меня это звучит как сценарий использования, где вы хотите что-то вроде «хранилища реляционных столбцов», как описано здесь .

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

При извлечении массивов вам не только не нужно объединять его с другой таблицей, полученной в результате нормализации, но вы можете извлекать ряды как массив, а не как хеш.

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

Вот еще один доклад, который может быть актуальным, даже если это не совсем актуальное или развертываемое решение.


6

Я бы порекомендовал вам попробовать разделить ваш стол. У нас более 80 миллионов строк в одной таблице (данные фондового рынка), и у нас нет проблем с быстрым доступом к ней.

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

http://dev.mysql.com/doc/refman/5.1/en/partitioning-limitations.html

http://www.slideshare.net/datacharmer/mysql-partitions-tutorial


5

Да, но...

Я работал с таблицами, в которых было 2 миллиарда строк. Однако ожидалось, что только запросы, использующие PK, будут быстрыми.

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

КСТАТИ. Ваша схема выглядит как нечто, что может вписаться в решение NoSQL, используя в run_idкачестве ключа хеширования для спектров и в spectrum_idкачестве ключа хеширования для точек данных.


4

Я написал об этой теме в своем блоге: http://www.tocker.ca/2013/10/24/improving-the-performance-of-large-tables-in-MySQL.html

Чтобы повторить некоторые ключевые моменты:

  • B-деревья ухудшаются по мере того, как они становятся больше и не помещаются в память (MySQL здесь не одинок).
  • InnoDB имеет некоторые функции, которые помогают поддерживать некоторую производительность (изменение буферизации; ранее называлось «вставка буфера»).
  • Разделение может также помочь.

В комментариях к моему посту Тим Каллаган ссылался на это: http://www.tokutek.com/resources/benchmark-results/benchmarks-vs-innodb-hdds/#iiBench

Который показывает вставку 1 млрд строк с помощью теста iibench.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.