Чи може MySQL розумно виконувати запити на мільярдах рядків?


283

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

Формат введення

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

Система господарів

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

На сервері працюють деякі інші сервіси, використовуючи незначний час процесора.

Статистика файлів

| ------------------ + -------------- |
| кількість файлів | ~ 16 000 |
| загальний розмір | 1.3 TiB |
| хв. розмір | 0 байт |
| максимальний розмір | 12 ГіБ |
| означають | 800 МіБ |
| медіана | 500 МіБ |
| загальних точок даних | ~ 200 млрд. |
| ------------------ + -------------- |

Загальна кількість точок даних - це дуже приблизна оцінка.

Запропонована схема

Я планую робити «правильно» (тобто нормалізувати дані, як божевільні), і тому я мав би runsтаблицю, spectraтаблицю з іноземним ключем до runsта datapointsтаблицю із зовнішнім ключем до spectra.

Питання щодо точки 200 мільярдів

Я буду аналізувати різні спектри та, можливо, навіть декілька прогонів, в результаті чого запити можуть торкнутися мільйонів рядків. Якщо припустити, що я індексую все належним чином (що є темою для іншого питання), і я не намагаюся перемішувати сотні MiB по всій мережі, чи віддалено правдоподібно для MySQL це впоратися?

додаткова інформація

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

Ці дані записуються одноразово, тому ефективність оновлення та безпека транзакцій не викликають занепокоєння.

Мій наївний план схеми бази даних:

runs стіл

| назва стовпця | тип |
| ------------- + ------------- |
| id | ПЕРШИЙ КЛЮЧ |
| start_time | TIMESTAMP |
| назва | ВАРЧАР |
| ------------- + ------------- |

spectra стіл

| назва стовпця | тип |
| ---------------- + ------------- |
| id | ПЕРШИЙ КЛЮЧ |
| назва | ВАРЧАР |
| індекс | INT |
| спектр_типу | INT |
| представництво | INT |
| run_id | ІНТЕРНЕТ КЛЮЧ |
| ---------------- + ------------- |

datapoints стіл

| назва стовпця | тип |
| ------------- + ------------- |
| id | ПЕРШИЙ КЛЮЧ |
| спектр_id | ІНТЕРНЕТ КЛЮЧ |
| мз | ДВОЙНИЙ |
| num_counts | ДВОЙНИЙ |
| індекс | INT |
| ------------- + ------------- |

Це розумно?


Отже, як ви, можливо, змогли зробити висновок, я програміст, а не біолог у лабораторії, тому я майже не знаю науки, як фактичних вчених.

Ось сюжет єдиного спектру (сканування) такого роду даних, з яким я буду мати справу:

Скріншот переглядача

Мета програмного забезпечення - з'ясувати, де і наскільки значущі піки. Ми використовуємо фірмовий програмний пакет, щоб розібратися в цьому зараз, але ми хочемо написати власну програму аналізу (в R), щоб ми знали, що, до біса, відбувається під аркушами. Як бачимо, переважна більшість даних є нецікавими, але ми не хочемо викидати потенційно корисні дані, пропущені нашим алгоритмом. Після того, як у нас з’явиться список можливих піків, якими ми задоволені, решта конвеєра використовуватиме цей піковий список, а не необроблений список точок даних. Я припускаю, що досить було б зберігати необроблені точки даних як велику крапку, щоб їх можна було повторно аналізувати, якщо потрібно, але зберігати лише піки як окремі записи бази даних. У такому випадку було б лише пару десятків піків на спектр, тож шалене масштабування не повинно бути '



8
Оскільки це необроблені дані вимірювання мас-спектрометра A / D, здається, що це дійсно нерозумно зберігати їх у базі даних. Я б взяв свої необроблені дані, скидав їх, обробляв і зберігав оброблені РЕЗУЛЬТАТИ в базі даних. Результатами будуть: (а) форми хвиль, що зберігаються по одній формі хвилі в рядку; (б) інші дані, пов'язані з тими формами хвиль, як калібрувальні криві, та (в) рядки результатів у базі даних. Це дозволить вирізати мільярди рядків від твого дизайну. Коли ви хочете повторно запустити початковий аналіз, ви б ефективно редагували деякі параметри, виконували гігантські операції обчислення та зберігали нові результати у db.
Warren P

Відповіді:


115

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

Як правило, зберігати двійкові дані в базах даних є неправильним більшість часу. Зазвичай існує кращий спосіб вирішення проблеми. Хоча зберігати бінарні дані у реляційній базі даних не є суттєво неправильним, часто недоліки переважають надбавки. Реляційні бази даних, як натякає ім'я, найкраще підходять для зберігання реляційних даних. Двійкові дані не є реляційними. Це додає розмір (часто значно) базам даних, може погіршити продуктивність і може спричинити питання щодо збереження мільярдних екземплярів MySQL. Хороша новина полягає в тому, що є бази даних, які особливо добре підходять для зберігання двійкових даних. Один з них, хоча і не завжди легко очевидний, - це ваша файлова система! Просто придумайте структуру імен файлів і файлів для ваших бінарних файлів,

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


5
Чому вважається неправильним зберігання двійкових даних у базі даних? (Прошу частково тому, що мені цікаво, але також тому, що я можу придумати

15
Якщо двійкові дані не мають значення окремо, вони не повинні зберігатися як унікальний рядок. Піксель 500x325 на зображенні не має значення.

1
Це дуже вдалий момент. Ми, мабуть, повинні тримати необроблені файли навколо, якщо нам доведеться знову витягувати речі пізніше, але аналогія зберігання зображень є чудовою. Нам ніколи не знадобиться доступ до кожної точки даних (якщо тільки ми не повторимо пікове вилучення), тому просто зберігання вилученої статистичної інформації було б набагато краще.
haxney

107

Я колись працював із дуже великою базою даних (Terabyte +) MySQL. Найбільший стіл у нас був буквально понад мільярд рядків. Для цього використовується MySQL 5.0, тому можливо, що все покращилося.

Це спрацювало. MySQL обробляв дані правильно більшу частину часу. Це було надзвичайно непростим. (Якщо ви хочете мати шість доступів на рівні сигми з терабайтними даними, не використовуйте MySQL.

Просто створення резервної копії та зберігання даних було складним завданням. Щоб відновити таблицю, якщо нам потрібно, знадобиться кілька днів.

У нас були численні таблиці в діапазоні рядків 10-100 мільйонів. Будь-які суттєві приєднання до столів були занадто трудомісткими і тривали б назавжди. Таким чином, ми написали збережені процедури, щоб "ходити" по таблицях і обробляти об'єднання проти діапазонів "id". Таким чином ми б обробляли дані 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 може допомогти у вирішенні проблем із швидкістю, але це може не допомогти в цілому в роботі DBA, яку потрібно виконати - що може бути вбивцею.


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

70

нормалізація даних як божевільна

Нормалізація даних як божевільних може бути не правильною стратегією в цьому випадку. Зберігайте параметри відкритими, зберігаючи дані як у нормованій формі, так і у вигляді матеріалізованих подань, що дуже підходять вашій програмі. Ключовим в цьому типі програм є НЕ написання спеціальних запитів. Моделювання запитів важливіше, ніж моделювання даних. Почніть зі своїх цільових запитів і працюйте над оптимальною моделлю даних.

Is this reasonable?

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

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

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

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


Ви проаналізували свої потреби в записі проти потреб у читанні? Буде дуже спокусливо скинути SQL і перейти до нестандартних механізмів зберігання даних. На мою думку, це має бути останнім засобом.

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

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


33

Коротка відповідь - кваліфікований "так", оскільки кількість рядків збільшує важливу точну схему, вибрані типи даних та операції.

Наскільки ви нормалізуєте свої дані, залежить від операцій, які ви плануєте виконати над збереженими даними. Зокрема, ваша таблиця "точок даних" видається проблематичною - чи плануєте ви порівнювати n-ту точку з будь-якого даного спектра з mth будь-якого іншого? Якщо ні, зберігання їх окремо може бути помилкою. Якщо ваші точкові дані не стоять окремо, але мають сенс лише в контексті їх асоційованих спектрів, вам не потрібен ПЕРВИЧНИЙ КЛЮЧ - достатньо іноземного ключа до спектрів і "n-го" стовпчика (ваш "індекс")? .

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

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

Після того, як рядки таблиці мають фіксовану ширину, ви можете зменшити кількість байтів, ретельно оцінивши цілі типи даних MySQL (деякі з яких є нестандартними). Кожна 1-байтова економія, яку ви зможете отримати, перетворивши 4-байт INT в 3-байт MEDIUMINT, економить ~ 1 МБ на мільйон рядків - це означає менше вводу / виводу диска та більш ефективне кешування. Використовуйте найменші можливі типи даних, від яких ви можете піти . Уважно оцініть типи плаваючої точки і перевірте, чи можете ви замінити 8-байтові ДВОБЛИ на 4-байтові FLOAT або навіть <8 -байтні NUMERIC з фіксованою точкою . Проведіть тести, щоб переконатися, що те, що ви виберете, не буде кусати вас згодом.

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

Найголовніше, що б ви в кінцевому підсумку не робили, не вважайте, що ви вибрали ідеальну схему, а потім сліпо почніть скидати 10 мільйонів записів. Хороші проекти потребують часу, щоб розвиватися. Створіть великий, але керований (скажімо, 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

Гм ... Я бачу по-справжньому дві причини, чому ви вибрали б такий тип даних:

  • вам дійсно потрібно робити будь-яку точку даних проти будь-яких запитів
  • ви маєте намір виконати всю свою логіку в SQL

Тепер я б запропонував уважно поглянути на ваші вимоги і переконатися, що принаймні одне з перерахованих вище припущень є правдивим. Якщо жодне не відповідає дійсності, ви просто робите все повільніше. Для такого типу наборів даних я б запропонував спочатку з’ясувати, як очікується доступ до даних, яку точність вам знадобиться тощо, а потім розробити свою базу даних навколо них.

PS: Майте на увазі, що вам знадобиться щонайменше 36 + 5 байт на точку даних, тому з точками даних 200B, які мають забезпечити принаймні 8,2 ТБ необхідного місця.

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


12

Редагувати:

НЕ РОБИТИ ЦЕ В MYSQL З ДАНИМИ, ЗБЕРЕЖЕНИМ НА ОДИННОМУ ДИСКУ. Просто прочитання такої кількості даних з одного носія займе години. Вам потрібно ВИМОГАТИСЯ, а не вгору.

І вам потрібно денормалізувати свої дані, якщо ви хочете зробити ефективний аналіз даних. Ви тут не проектуєте онлайн-систему. Ви хочете розчавити цифри, спроектуйте їх відповідно.

Оригінальна відповідь під рядком.


Відповідь буде залежати від ваших запитів, MySQL може бути не найкращим інструментом для цієї роботи. Ви можете подивитися на рішення, яке ви можете масштабувати "поза", а не "вгору". Якщо ви готові докласти певних зусиль, можливо, вам варто поглянути на рішення щодо зменшення карт, наприклад, Hadoop.

Якщо ви хочете зробити більше спеціальних запитів , рішення BigQuery від Google може вам підійти. Відповідна презентація від Google I / O 2012: Зниження великих даних за допомогою BigQuery

Отже, рішення буде залежати від того, чи це одномоментна річ і чи ви хочете обґрунтовано підтримувати спеціальні запити.


9

Ніхто не згадував, таким чином, мою пропозицію. Погляньте на широкомасштабні рішення MySQL . Наприклад, дивіться цю високо цінувану презентацію tumblr .

Концепція така:

  • Замість однієї надзвичайно великої бази даних
  • Використовуйте багато маленьких, що містять частини оригінальних даних

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

Однак виникнуть проблеми, якщо вам потрібно буде виконувати запити над різними фрагментами.


Якщо хтось зацікавився, я дуже давно зробив додаток привітного світла. Це обговорюється тут у публікації в блозі. Я використовував RavenDB та C #, але деталі не мають значення, і ідея така ж.


7

На якій машині зберігаються дані? Це спільні пристрої зберігання даних?

Кінцевим фактором, який буде диктувати час запиту, будуть ваші жорсткі диски. Бази даних та їх оптимізатори запитів покликані максимально зменшити кількість вводу / виводу диска. Враховуючи, що у вас є лише 3 таблиці, це буде зроблено досить надійно.

Швидкість читання / запису жорсткого диска буде в 200-300 разів меншою, ніж швидкість пам'яті. Шукайте жорсткі диски з дуже швидкою затримкою та швидкістю читання та запису. Якщо всі ці дані є на одному накопичувачі 2 ТБ, ви, ймовірно, будете довго чекати, коли запити завершаться. Затримка жорсткого диска становить ~ 10–15 мілісекунд, а затримка пам’яті менше 10наносекунд. Затримка жорсткого диска може бути на 1000-2000x повільнішою, ніж затримка пам'яті. Переміщення механічної руки на жорсткому приводі є НАЙСЛУГОЮ річчю у всій цій системі.

Скільки оперативної пам’яті у вас є? 16 Гб? Скажімо, що ви можете зберігати 32 записи. У вас 16000 файлів. Якщо ви збираєтесь лінійно сканувати всі точки даних, ви можете легко закінчити за 5-10 секунд у самому пошуку часу. Тоді коефіцієнт швидкості передачі 50 мб / с? Близько 7 годин. Крім того, будь-які тимчасово збережені дані повинні бути збережені на жорсткому диску, щоб звільнити місце для читання нових даних.

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

Також добре допомагає зменшити кількість вкладених запитів. Вкладені запити призводять до тимчасових таблиць, які ще більше розберуть ваш жорсткий диск. Я сподіваюся, що у вас на Твердому диску є ВЕЛИКИ вільного місця.

Оптимізація запитів може розглядати лише 1 запит за один раз. Отже, вкладені оператори вибору не можна оптимізувати. ЗАРАЗ, якщо ви знаєте, що конкретний вкладений запит призведе до повернення невеликого набору даних, збережіть його. Оптимізація запитів використовує гістограми та грубі припущення, якщо ви знаєте щось про дані та запит, тоді продовжуйте і виконайте це.

Чим більше ви знаєте про спосіб зберігання ваших даних на диску, тим швидше ви зможете писати запити. Якщо все зберігалося послідовно на первинному ключі, може бути корисним сортування первісних ключів, повернених із вкладеного запиту. Крім того, якщо ви можете скоротити набір наборів даних, які вам потрібно заздалегідь проаналізувати, зробіть це. Залежно від вашої системи, ви переглядаєте приблизно 1 секунду передачі даних на файл.

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

Що стосується коментарів щодо денормалізації таблиці. Я думаю, що найкраще просто зберігати точки даних у більших групах (можливо, як спектри), а потім робити аналіз даних у python або мові, яка взаємодіє з базою даних. За винятком вашого майстра SQL.


3
Ви підкреслюєте величезну різницю між жорсткістю диска та затримкою пам’яті, але ваші цифри вимикаються в 1000 разів. Якщо жорсткі диски мають затримку близько 10 мс, а пам’ять 10нс, затримки не відрізняються коефіцієнтом 1000, а коефіцієнтом 1 000 000!
спектр256

6

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

Можливо, я нерозумію конструкцію, але якщо ви в основному маєте справу з великою колекцією масивів, зберігання їх у типових таблицях, орієнтованих на рядки, означає, що кожен елемент схожий на фрагмент. Якщо вам цікаво дивитись на фрагменти типовим чином, це має сенс, але це може бути менш ефективно, якщо ви дійсно переглядаєте цілі стовпчики одночасно.

Коли ви отримуєте масиви, не тільки вам не потрібно буде з'єднувати його з іншою таблицею, що є результатом вашої нормалізації, але ви можете отримати серію як масив, а не хеш.

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

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


6

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

Залежно від того, як ви збираєтесь шукати свої дані, слід розробити свої розділи. У нашому випадку за датою працює добре, оскільки ми запитуємо конкретні дати.

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

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


5

Так, але...

Я працював з таблицями, які мали 2 мільярди рядків. Однак очікувалося, що тільки запити, що використовують ПК, будуть швидкими.

Найголовніше, що в апаратному забезпеченні було достатньо оперативної пам’яті, щоб вмістити цілі таблиці в пам'ять. Коли це стало проблемою (максимум на 96 Гб на той час), перейшли до вертикального розподілу, зберігаючи розмір столу, встановленого на кожній машині, досить малим, щоб все ще вмістився в пам'яті. Крім того, машини були підключені через 10Gb волокно, тому пропускна здатність мережі не була великою проблемою.

До речі. ваша схема виглядає як щось, що могло б вписатись у рішення 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.