Название: Партіціювання даних в mysql Отправлено: Efendy от 25 Июня 2024, 15:28:22 Створив гілку, але скоріше тільки для себе - щоб не забути які я робив дослідження. Ну якщо комусь є щось сказати, можете висловлюватись)
Чим більше даних в базі даних, тім повільніше вона працює, це очевидно. Але в більшості випадків потрібні актуальні дані - ну, наприклад, платежи тільки за останній період. По дефолту при переході в розділ "платежі" там як раз і показуються платежі за останні декілька місяців. Для таких ситуацій в базах даних використовують фішку "партіціювання" - це коли дані однієї таблиці розділяються не декілька, умовно кажуючи таблиць. Наприклад, можна розділити по даті: за 2023рік в такий таблиці, за 2024й в іншій таблиці і так далі. Насправді для нас це виглядає як одна таблиця, а всю работу під капотом виконує субд. Що нам дає це: дікілька таблиць меньше ніж одна. Тому і запис і вибірка будуть швидше. Це і є основна ціль. Виникає питання: а як вибирати інформацію з великого діапазону, коли частина буде в одній, а частина в нішій "таблиці" (цях)? Величезний плюс в тому, що це робить сама СУБД! Вона знає коли звернутися до однієї таблиці, а коли до декількох. Все. Далі піде технічна інфа, скоріше за все тільки для мене) Я провів дослідження: * як зробити партіціювання * буде воно робити з реплікацією мастер-слейв Підняв 2 докера з mysql-8 і налаштував реплікацію. Щось додаю на мастері - і це з'являється на слейві. Ура мені і докеркомпоузу. Намагаюсь зробити партіціювання по полю time: Код: ALTER TABLE pays PARTITION BY RANGE (time) ( Ідея така: дані до 24 року зберігаю в партиції p2023, до 25го - в p2024, інші в pmax. Але це не працює: Код: ERROR 1503 (HY000): A PRIMARY KEY must include all columns in the table's partitioning function (prefixed columns are not considered На цьому можна було закінчити. Короче, у мускула (чи скрізь так) обмеженне партіціювання - неможна розділяти на часті, якщо поле, по якому йде розділення не входить в прімарі кі. Я не знаю чому, може логіка в цьому є. Але мені потрібне вирішення проблеми. Ладно, я використав більш простий варіант - розділяти по id. Нам потрібно буде просто вибрати який максимальний id в якому році: Код: ALTER TABLE pays PARTITION BY RANGE (id) ( 3 і 8 маленьки числа бо це все тестово. Код: SELECT PARTITION_NAME, TABLE_ROWS показує що робить: Код: +----------------+------------+ Виконав це на слейві - все робить так само. Як отримати доступ до ціх розділів напряму? В постгресі я міг, тут не можу. В принципі, це не потрібно, але є випадок коли нам би це знадобилося - коли ми хочемо бекапити тільки частину поточного року. В інших бекапах будуть данні за інші роки, тому нам не потрібно втрачати час і дисковий простір на бекап старих даних. mysqldump дампить всю таблицу. Ну ок, не фартануло по цьому питанню. Але ж з гуглежем в 5 хвилин я можу і помилятися, просто для мене це питання непринципово. Ітак. Як подивиться, що ми маємо якийсь профіт: Код: explain select * from pays where id<3; тут бачимо, що профіт є - вибірка йде чисто з розділу p2023 Перевіряємо, що субд може шукати одразу по декількох розділів: Код: explain select * from pays; Але в бою ми профіта не отримаємо, бо нам був би корисний такий запит: Код: explain select * from pays where time<unix_timestamp('2020-01-01'); Але він, очиковано, ніякого профіту не дає: Код: +----+-------------+-------+------------------+-------+---------------+------+---------+------+------+----------+-----------------------+ Тобто на даном етапі я не бачу варіанту отримати плюси від партіціювання. Можливо ми щось виграємо на швидкості вставки даних в таблицю pays. Але це потрібно проводити дослідження на великіх даних. При цьому я не думаю, що зараз є у когось проблеми саме при створюванні даних в таблиці pays. Але. Все може бути не так як я думаю, бо я витратив на все 4 години, а це малова-то для експертної думки |