Додавання індексу до великих таблиць mysql


13

У мене стіл

| base_schedule_line_items | CREATE TABLE base_schedule_line_items(
idint (10) unsigned NOT NULL AUTO_INCREMENT,
installmentint (10) unsigned NOT NULL,
on_datedate NOT NULL,
actual_datedate DEFAULT NULL,
payment_typeint (11) NOT NULL,
scheduled_principal_outstandingdecimal (65,0) NOT NULL,
scheduled_principal_duedecimal (65,0) NOT NULL,
scheduled_interest_outstandingдесяткова (65,0) NOT NULL,
scheduled_interest_dueдесяткова (65,0) NOT NULL,
currencyint (11) NOT NULL,
updated_atdatetime NOT NULL DEFAULT '2013-01-06 14:29:16', time date
created_atNOT NULL DEFAULT ' 2013-01-06 14:29:16 ',
loan_base_schedule_idint (10) без підпису NOT NULL,
lending_idint (10) без підпису NOT NULL,
rescheduletinyint (1) DEFAULT' 0 ',
PRIMARY KEY ( id),
KEY index_base_schedule_line_items_loan_base_schedule ( loan_base_schedule_id), KEY index_bslt_spd( scheduled_principal_due),
КЛЮЧ index_bslt_lending(lending_id),
KEY index_bslt_actualdate( actual_date),
KEY index_bslt_spsila ( loan_base_schedule_id, scheduled_principal_due, scheduled_interest_due, actual_date),
KEY index_bslt_ondate( on_date),
KEY index_bslt_oa( on_date, actual_date),
KEY index_bslt_ol( on_date, loan_base_schedule_id),
KEY index_bslt_oli( on_date, lending_id)
) ENGINE = InnoDB AUTO_INCREMENT = 30410126 DEFAULT CHARSET = utf8 |

Тепер ця таблиця містить 30 мільйонів записів, мені потрібно додати ще два індекси до цього, і як би потрібні роки, щоб його додати.

змінити таблицю base_schedule_line_items додати індекс index_bslt_sla (raspored_principal_due, фактичний_даний, кредитування_id);
змінити таблицю base_schedule_line_items додати індекс index_bslt_ssla (raspored_principal_due, запланований_interest_due, lending_id, фактичний_date);

Я використовував нижчезазначений запит, щоб дізнатися розмір таблиці

ВИБІРТЕ Ім'я_матеріалу AS "Таблиці", круглі (((data_length + index_length) / 1024/1024), 2) "Розмір у МБ" ВІД_інформації__схеми.TABLES WHERE table_schema = "my_database_name";

Результат вийшов як

base_schedule_line_items | 20111.00

Я використовував це лише для того, щоб обчислити довжину даних і залишив відстань індексу

ВИБІРТЕ ім'я таблиці_АС "Таблиці", круглі (((data_length) / 1024/1024), 2) "Розмір у МБ" ВІД інформації_схеми.TABLES WHERE table_schema = "my_database_name";

і результат був

base_schedule_line_items | 9497.00

Індекси

KEY index_bslt_actualdate (фактичний_date),
KEY index_bslt_spsila (заимствование_базы_схедуле_ид, заплановано_принцип_дуе, заплановано_интерес_дуе, фактично_даче),
КЕЙ індекс_бсл_ондате (он_дате),
КЕЙ індекс_бсл_оа (on_dete, дата_да ,
_да ,_да ,_да ,
_да ,_да ,_да , _да ,_да , _да ,_да ,_да , _да ,_да ,_да , _да ,_да , _да ,_да ,_да , _да ,_да ,_да , _да ,_да , _да ,_да ,_да , _да ,_да ,_да , _да ,_да , _да ,_да ,_да , _да ,_да ,_да , _да ,_да , _да ,_да ,_да , _да ,_да ,_,)

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

Відповіді:


16

Діяльність щодо зміни великих таблиць виконується поетапно:

  1. Створіть нову таблицю з обов'язковими полями та індексами, які говорять у тестовій БД (просто структура)
  2. Вивантажте дані з існуючої таблиці та завантажте їх у новостворену таблицю в тестовій БД
  3. Анонсуйте час простою :)
  4. Обміняйте таблиці перейменуванням - RENAME table ur_db.table_name to test.temp, test.table_name to ur_db.table_name, test.temp to test.table_name;Це атомна операція, яка займає частку секунди.
  5. Завантажте зайві записи в новостворену таблицю (записи, що з'явилися після скидання та завантаження). Цей крок можна зробити ще до кроку 3 також один раз, щоб скоротити час простою.
  6. І ваша система повернулася

Кілька приміток:

  1. Потрібно не вдарятись інформаційною схемою прямо так, спробуйте скористатися SHOW TABLE STATUS from db like 'table_name'
  2. Швидкість зміни таблиці більш-менш пов'язана зі швидкістю вводу / виводу. Минулого разу, коли ми запускали таблицю з прямими змінами (без вищезазначених кроків), у нас був 40 Гб + розмір столу, він займав близько 4 годин. Якщо ваші дані 20 Гб займають роки, ви працюєте на якійсь застарілій машині.
  3. Також падіння небажаних індексів, як, наприклад, index_bslt_ondate, index_base_schedule_line_items_loan_base_scheduleу деяких інших індексів, має найбільшу ліву колонку як індексовану колонку

Будь ласка, повідомте мене, якщо вам потрібні роз'яснення щодо будь-якого з цих кроків.

Редагувати: простий скрипт python для автоматизації процесу https://github.com/georgecj11/hotswap_mysql_table.git


10

Ви можете використовувати такий інструмент, як pt-online-schema-change, щоб додати індекс, не блокуючи додаток. Основна логіка така:

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

* Інструмент не працює, якщо на столі є тригери

Поведінку заміни та падіння можна відрегулювати на основі опцій, переданих інструменту.

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

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.