InnoDBのINFORMATION_SCHEMA TABLES Tableと実データのレコード数比率を出してみた
キャラメルコーンは一人で食うにはやはり一袋でかいなと痛感している@masudaKです。
information_schema.TABLESのデータどれくらい使えるだろうなと思い、簡単にデータ取ってみたので、その感想をば。
使ったMySQLのバージョンは5.5.24でございます。
「MySQL 5.5 Reference Manual :: 20.21 The INFORMATION_SCHEMA TABLES Table」には以下のように書かれていまして、
For InnoDB tables, the row count is only a rough estimate used in SQL
optimization. (This is also true if the InnoDB table is partitioned.)
要はInnoDBを使ってると行数のカウントはラフだよ、ざっくり出してるからねと書かれております。
SELECT table_name, table_rows FROM information_schema.TABLES WHERE table_schema = 'DB_NAME';
とやればそれっぽいデータ取れるんですが、実データとどれくらい違うんだろうと思い、ちょっと取ってみました。
更新も一切走ってなく、ディスクにフラッシュした状態で、↑で取得したデータと以下のスクリプトを元に取得したデータでざっくりと比較してみました。
#!/bin/bash -e USER='USER' PASS='PASS' DB='DB_NAME' LOG_FILE="./mysql_table_count.log" for TABLE in `mysql -u${USER} -p{PASS} -e "USE ${DB}; SHOW TABLES\G" | gawk '{ if (NR % 2 == 0) printf $2"\n"}'` do echo "----------- Getting ${TABLE} Information -----------------------------" | tee -a "${LOG_FILE}" mysql -u${USER} -p${PASS} -e "SELECT count(*) FROM ${DB}.${TABLE};" | tee -a "${LOG_FILE}" ELEVEL=$? if [ ${ELEVEL} -ne 0 ]; then echo "Failed: could not get information for ${TABLE}" | tee -a "${LOG_FILE}" else echo "Success: ${TABLE}" | tee -a "${LOG_FILE}" fi echo '----------------------------------------' | tee -a "${LOG_FILE}" done
結果は以下の様な感じ(かなり抜粋ですが…)。
以下の言う比率とは、information_schema.TABLESのtable_rowsカラムから得られた値を、COUNT(*)で取得した値で割った値です。なので、等しい場合は1となり、table_rowsの値が小さければ1より小さく、大きければ1より大きくなります。
|table_name |比率 | |table1 |1.000| |table2 |1.186| |table3 |0.961| |table4 |1.052| |table5 |1.060| |table6 |2.045| |table7 |1.023| |table8 |1.196| |table9 |0.909| |table10 |1.021| |table11 |1.273| |table12 |1.000| |table13 |0.929| |table14 |1.040| |table15 |0.939| |table16 |1.000| |table17 |0.996| |table18 |1.000| |table19 |1.015| |table20 |1.051| |table21 |1.000| |table22 |1.000| |table23 |0.854|
これでも一部ですが、やっぱ概算値だなぁと。2.045とかだとここまでずれるのかーと思ったり。
当然ではありますが、1.000、またはそれに近いのはレコード数がめちゃ小さいのが目立ちます。二桁とかそういうの。億でもそういうのは稀にあるので、そこら辺は難しいところですが、基本的にはレコード数は少なめですね。
大きくズレるの見るとレコード数少な目のものも大き目のものもありますが、よく更新されてるテーブルのような印象を受けます。更新処理が走るので、概算値がずれやすいのかなと。
いずれにせよ、深くは追えてないですが、上記のような印象を受けました。
InnoDBであまりcount(*)大量に走らせたくないのですが、たまにはということで。
あと、やっぱ5.5系は早いかもなーという気持ちも若干した次第です。