MySQL'de bir tablonun veri büyüklüğü ve indeks büyüklüğü nasıl tahmin edilir / tahmin edilir?


26

Ben bulma ediyorum bir tablonun boyutunu tahmin etmenin en iyi yolu nedir ben bloglar ve forumlar ama çalışılmış şey var bunun için herhangi bir kesin bir cevap bulamadı

Örneğin , InnoDB motorlu bir masamız var , diyelim ki (önümüzdeki 1 yıl içinde) 1 milyon kayıt olacak, yani bu dönemde bu tablonun tahmini veri büyüklüğü ve endeks büyüklüğü ne olacak.

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)

GÜNCELLEŞTİRME

Tahmini üst sınır ne olacak (maksimum tablo boyutu) 1 milyon kayıt olacak ve nasıl tahmin edebiliriz.


Bu harika. ancak indeks büyüklüğü sütununu akıllıca elde etmek mümkün. Bunun anlamı, indekslenmiş 5 sütunlu bir tablonuz varsa. Her birinin indeks büyüklüğünü alabilir miyiz? Bunu başka bir soru olarak soracağım. teşekkürler
Sushil

Yanıtlar:


51

Tablo açıklaması göz önüne alındığında, görüyorum

  • Veri satırı başına 66 bayt
  • Birincil anahtar için satır başına 4 bayt
  • Ülke kodu dizini için satır başına 7 bayt
    • Ülke için 3 bayt
    • Ülke koduna ekli, Kümelenmiş Anahtar için 4 bayt
  • Toplam 77 bayt veri ve anahtar
  • Bu, BTREE'ler veya Tablo Alanı Parçalama için temizlik faktörünü etkilemez.

Bir milyon satır için bu 77.000.000 bayt olur (73.43 MB)

Tablo ölçümü için, mydb.mytable dosyasının verilen tablo için bu sorguyu çalıştırabilirsiniz.

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;

Veritabanı ve Depolama Motoru tarafından gruplandırılmış tüm tabloları ölçmek için

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;

Bu sorguları çalıştırın ve veritabanı / motor disk kullanımındaki değişiklikleri takip edin.

Bir şans ver !!!


1
Bu, tüm tablo boyutlarınızı görüntülemek için gerçekten harika bir sorundur.
ghayes

CHAREğer varsa uzunlukları 3 ile çarpılır gerekmektedir CHARSET utf8. Genel gider, hesaplamanın iki katına veya üçe katlanmasıyla tahmin edilebilir.
Rick James

@RolandoMySQLDBA, bir tablonun "gerçek" satır boyutunu gerçek boyutla (sıkıştırılmış tablo) karşılaştırmak ve sıkıştırma oranını elde etmek amacıyla hesaplamak mümkün olup olmadığını biliyor musunuz?
ceinmart

@ ceinmart innodb_page_size sabittir (varsayılan olarak 16K veya 16384) ve satırların gruplandığı veya gruplandığı veya bölündüğü sınır olur. İnnodb_page_size öğesinin değiştirilmesi, iyi veya kötü verilerin depolanmasını değiştirebilir. Bir satırın ne kadar dolu veya seyrek olduğuna bağlı olarak (özellikle TEXT / BLOB / VARCHAR varlığında). En iyi ihtimalle, .ibd dosyasının boyutunu şema raporunun oranını tahmin ettiği ile karşılaştırmalısınız. ALTER TABLE ... ENGINE=InnoDB;Doğru bir oran elde etmek için NULL ALTER TABLE ( ) işlemi de yapmanız gerekebilir . Çaba buna değer olmayabilir.
RolandoMySQLDBA

@ ceinmart Aklınızda bulundurun şapka Innodb_page_size değişen tablo-tablo ayarı değildir. Verilerin tam ihracatını yapmak gerekir (Bkz mariadb.com/kb/en/library/how-to-change-innodb_page_size )
RolandoMySQLDBA

4

InnoDB tablolarını kullanıyorsanız, veri / bireysel dizinlerin boyutunu alabilirsiniz mysql.innodb_index_stats. 'Boyut' statı, sayfalardaki cevabı içerir, bu yüzden sayfa boyutu ile çarpmanız gerekir, yani varsayılan olarak 16K .

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

PRIMARY endeksi verinin kendisidir.


1
Bu, tabloda verilerinizin olduğunu varsayar; OP doldurmadan önce tahmin etmek istiyor gibi görünüyor.
Rick James

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';

Bu sorguyu uygulayarak bir tablo için Datave Indexbir tablo için kullanılan boyutu elde edebilirsiniz , Bu boyutu satırların sayısına göre kontrol edebilir ve 1 milyon satır için tahmin edebilirsiniz.


1
Emin değilim ama bu ne doğru sonuçlar verecek? Bunu hiç test ettin mi?
Abdul Manaf,

Aslında büyümeyi (%) wrt büyüklüğünü görmek için bu sorgu sonucunu periyodik olarak test ediyorum
Peter Venderberghe

0

Henüz bir bilginiz yoksa, işte bazı ipuçları. Aşağıdaki InnoDB için geçerlidir. (MyISAM çok daha basit ve daha küçük.)

CHARDeğişken uzunluklu sütunlar için kullanmayın . Ne CHARACTER SETkullanıyorsun Ascii'nin karakter başına bir bayta ihtiyacı var; utf8mb4'ün 1 ile 4 arasında olması gerekir.

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

Toplam = yaklaşık 80 bayt.

Çeşitli genel masraflar için 80 ile 2 ile 3 arasında bir çarpımı yapın. Büyük olasılıkla 1M sıralı masa 160MB ile 240MB arasında olacaktır.

Tek bir dizini ölçmek için CountryCode, 3 bayt için:

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.

Notlar:

  • Sadece yaprak düğümlerinin (BTrees) hesaplanması gerekir; yapraksız düğümler için ek yük tipik olarak % 1'dir.

  • Veri PRIMARY KEYile "kümelenmiştir", dolayısıyla hesaplamaya gerek kalmaz.

  • Açık bir PK'nız yoksa, üretilen PK için izin vermek üzere satır boyutuna 6 bayt eklemeniz gerekir.

  • ROW_FORMAT = COMPRESSEDsize 2: 1'lik bir büzülme verir. (Bu, 3: 1'lik tipik zip (vb.) Sıkıştırma oranı kadar iyi değildir.)

  • SHOW TABLE STATUS LIKE "tablename";'gerçek' boyutu hesaplamanın hızlı bir yoludur. Data_lengthVeri ve PK için bakınız ; Index_lengthikincil endeksler Data_freeiçin ve diğer bazı şeyler için.

  • Nadir olduğunu Index_lengthaşmak Data_length. Ancak bunun gerçekleşmesi “yanlış” değildir.


-1

Bu sıkıcı. Ancak detaylar belgelerde .

Mümkün olduğu kadar doğru olmak için, nadiren gerekli olan, tablo yapısı ve indeks yapısı hakkında da okumalısınız.

Ayakkabının içinde olsaydım, masayı kurardım, milyonlarca test verisiyle doldururum ve boyuttaki değişikliği ölçerdim. Uygulamanıza bağlı olarak, işlem günlüğü dosyalarının boyutunu da hesaba katmanız gerekebilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.