Як оцінити / передбачити розмір даних та розмір індексу таблиці в MySQL


26

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

Для прикладу, ми маємо таблицю City з двигуном InnoDB , скажемо, що в майбутньому (у наступному 1 році) він буде мати 1 мільйон записів, таким, яким буде орієнтовний розмір даних та розмір індексу цієї таблиці за цей період.

mysql> desc City;
+-------------+----------+------+-----+---------+----------------+
| Field       | Type     | Null | Key | Default | Extra          |
+-------------+----------+------+-----+---------+----------------+
| ID          | int(11)  | NO   | PRI | NULL    | auto_increment |
| Name        | char(35) | NO   |     |         |                |
| CountryCode | char(3)  | NO   | MUL |         |                |
| District    | char(20) | NO   |     |         |                |
| Population  | int(11)  | NO   |     | 0       |                |
+-------------+----------+------+-----+---------+----------------+
5 rows in set (0.03 sec)

ОНОВЛЕННЯ

Якою буде прогнозована верхня межа (Максимальний розмір таблиці) з 1 мільйоном записів і як ми можемо її оцінити.


Це чудово. але чи можна зрозуміти стовпчик розміру індексу. Що означає, якщо у вас є таблиця з індексованим (скажімо) 5 стовпцями. Чи можемо ми отримати розмір індексу кожного з них? Я поставлю це як інше питання. спасибі
Sushil

Відповіді:


51

Враховуючи опис таблиці, я бачу

  • 66 байт на рядок даних
  • 4 байти в рядку для основного ключа
  • 7 байт у рядку для індексу коду країни
    • 3 байти для країни
    • 4 байти для кластерного ключа, доданого до коду країни
  • Всього 77 байт даних і ключів
  • Це не враховує ведення господарства для BTREE або фрагментації простору таблиць

Для мільйона рядків це було б 77 000 000 байт (73,43 МБ)

Що стосується вимірювання таблиці, для даної таблиці mydb.mytable можна виконати цей запит

SELECT 
    CONCAT(FORMAT(DAT/POWER(1024,pw1),2),' ',SUBSTR(units,pw1*2+1,2)) DATSIZE,
    CONCAT(FORMAT(NDX/POWER(1024,pw2),2),' ',SUBSTR(units,pw2*2+1,2)) NDXSIZE,
    CONCAT(FORMAT(TBL/POWER(1024,pw3),2),' ',SUBSTR(units,pw3*2+1,2)) TBLSIZE
FROM
(
    SELECT DAT,NDX,TBL,IF(px>4,4,px) pw1,IF(py>4,4,py) pw2,IF(pz>4,4,pz) pw3
    FROM 
    (
        SELECT data_length DAT,index_length NDX,data_length+index_length TBL,
        FLOOR(LOG(IF(data_length=0,1,data_length))/LOG(1024)) px,
        FLOOR(LOG(IF(index_length=0,1,index_length))/LOG(1024)) py,
        FLOOR(LOG(data_length+index_length)/LOG(1024)) pz
        FROM information_schema.tables
        WHERE table_schema='mydb'
        AND table_name='mytable'
    ) AA
) A,(SELECT 'B KBMBGBTB' units) B;

Для вимірювання всіх таблиць, згрупованих за базою даних та механізмом зберігання даних

SELECT
    IF(ISNULL(DB)+ISNULL(ENGINE)=2,'Database Total',
    CONCAT(DB,' ',IFNULL(ENGINE,'Total'))) "Reported Statistic",
    LPAD(CONCAT(FORMAT(DAT/POWER(1024,pw1),2),' ',
    SUBSTR(units,pw1*2+1,2)),17,' ') "Data Size",
    LPAD(CONCAT(FORMAT(NDX/POWER(1024,pw2),2),' ',
    SUBSTR(units,pw2*2+1,2)),17,' ') "Index Size",
    LPAD(CONCAT(FORMAT(TBL/POWER(1024,pw3),2),' ',
    SUBSTR(units,pw3*2+1,2)),17,' ') "Total Size"
FROM
(
    SELECT DB,ENGINE,DAT,NDX,TBL,
    IF(px>4,4,px) pw1,IF(py>4,4,py) pw2,IF(pz>4,4,pz) pw3
    FROM 
    (SELECT *,
        FLOOR(LOG(IF(DAT=0,1,DAT))/LOG(1024)) px,
        FLOOR(LOG(IF(NDX=0,1,NDX))/LOG(1024)) py,
        FLOOR(LOG(IF(TBL=0,1,TBL))/LOG(1024)) pz
    FROM
    (SELECT
        DB,ENGINE,
        SUM(data_length) DAT,
        SUM(index_length) NDX,
        SUM(data_length+index_length) TBL
    FROM
    (
       SELECT table_schema DB,ENGINE,data_length,index_length FROM
       information_schema.tables WHERE table_schema NOT IN
       ('information_schema','performance_schema','mysql')
       AND ENGINE IS NOT NULL
    ) AAA GROUP BY DB,ENGINE WITH ROLLUP
) AAA) AA) A,(SELECT ' BKBMBGBTB' units) B;

Запустіть ці запити, і ви можете відслідковувати зміни у використанні диска бази даних / двигунів.

Спробувати !!!


1
Це дійсно чудовий запит для перегляду всіх розмірів вашої таблиці.
ghayes

Ці CHARдовжини повинні бути помножені на 3 , якщо у вас є CHARSET utf8. Весь накладні витрати можуть бути оцінені шляхом подвоєння або потрійного обчислення.
Рік Джеймс

@RolandoMySQLDBA, чи знаєте ви, чи можливо обчислити "реальний" розмір рядка таблиці з метою порівняння з реальним розміром (стисла таблиця) і отримати співвідношення стиснення?
ceinmart

@ceinmart innodb_page_size фіксується (за замовчуванням 16K або 16384) і стає межею, де рядки та згруповані чи розділені. Зміна innodb_page_size може змінити зберігання даних на добро чи погано. Залежить від того, наскільки заповнений чи розріджений ряд (особливо за наявності TEXT / BLOB / VARCHAR). У кращому випадку слід порівняти розмір файлу .ibd з тим, що звітують схеми, щоб оцінити співвідношення. Вам також може знадобитися виконати NULL ALTER TABLE ( ALTER TABLE ... ENGINE=InnoDB;), щоб отримати точне співвідношення. Зусилля, можливо, цього не варто.
RolandoMySQLDBA

@ceinmart Майте на увазі, що зміна innodb_page_size - це не налаштування таблиці за столом. Вам потрібно буде здійснити повний експорт даних (Див. Mariadb.com/kb/uk/library/how-to-change-innodb_page_size )
RolandoMySQLDBA

4

Якщо ви використовуєте таблиці InnoDB, ви можете отримати розмір даних / окремих індексів з mysql.innodb_index_stats. Статистика "розміру" містить відповідь у сторінках, тому її потрібно помножити на розмір сторінки, тобто 16K за замовчуванням .

select database_name, table_name, index_name, stat_value*@@innodb_page_size
from mysql.innodb_index_stats where stat_name='size';

ІНДЕКС ПЕРШИЙ - це самі дані.


1
Це передбачає, що у вас є дані в таблиці; схоже, що ОП хоче оцінити перед заселенням.
Рік Джеймс

0
SELECT  Table_NAME "tablename",
           data_length   "table data_length in Bytes",
           index_length  "table index_length in Bytes",
           data_free  "Free Space in Bytes"
    FROM  information_schema.TABLES  where  Table_schema = 'databasename';

виконавши цей запит, ви можете отримати розмір, використаний для таблиці Dataта Indexтаблицю. Ви можете перевірити цей розмір проти # рядків та передбачити 1 мільйон рядків


1
Я не впевнений, але це дасть якісь точні результати? ви тестували це коли-небудь?
Абдул Манаф

Насправді я періодично тестую цей результат запиту, щоб побачити розмір (%) wrt
Peter Venderberghe

0

Якщо у вас ще немає даних, ось кілька порад. Наступне стосується InnoDB. (MyISAM набагато простіший і менший.)

Не використовувати CHARдля стовпців змінної довжини. Що CHARACTER SETви використовуєте? Ascii потрібен один байт на символ; utf8mb4 потребує від 1 до 4.

4 bytes per INT
35 for CHAR(35), if ascii or latin1; varchar is probably less
3 for the country code; it is fixed length
etc

Всього = близько 80 байт.

Помножте 80 на 2 і 3 для обліку різних накладних витрат. Швидше за все, таблиця рядків 1М буде знаходитись між 160МБ і 240МБ.

Для вимірювання одного індексу, наприклад, CountryCode3 байти:

3 bytes data
4 bytes for the PK (implicitly included with any secondary key)
25 bytes basic overhead
32 total
times 1.5 -- overhead for BTree that was randomly inserted into
48MB -- total for 1M rows.

Примітки:

  • Необхідно обчислити лише вузли листя (BTrees); накладні витрати для не листкових вузлів зазвичай становлять 1%.

  • Це PRIMARY KEY"кластеризовано" з даними, тому обчислювати їх не потрібно.

  • Якщо у вас немає явного ПК, тоді вам потрібно додати 6 байт до розміру рядка, щоб дозволити виготовлений ПК.

  • ROW_FORMAT = COMPRESSEDдає приблизно усадку 2: 1. (Це не так добре, як типовий коефіцієнт стиснення zip (тощо) 3: 1.)

  • SHOW TABLE STATUS LIKE "tablename";це швидкий спосіб обчислити "фактичний" розмір. Дивіться Data_lengthдані та ПК; Index_lengthдля вторинних індексів та Data_freeдля деяких інших матеріалів.

  • Це Index_lengthперевищує рідко Data_length. Однак це не "неправильно", щоб це сталося.


-1

Це нудно. Але деталі - у документах .

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

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

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