2011-12-24 5 views
13

InnoDBのSHOW TABLE STATUSが返す値に頼るべきではないことを知っています。 特に、行数と平均データ長。なぜinnodbのSHOW TABLE STATUSが信頼できないのですか?

しかし、私はある時点で正確な値が取られていると思っていました。それから、innodbはANALYZEテーブルや他のまれなイベントでのみリフレッシュします。

代わりに、私は同じテーブルの5秒間に5回SHOW TABLE STATUSを実行し、毎回完全に異なる数字を得ることができます(テーブルに挿入/削除アクティビティがないのに)

実際にこれらの値はどこから来ていますか?彼らはinnodbでちょうど腐敗していますか?

答えて

20

公式MySQL 5.1 documentationは、InnoDBがSHOW TABLE STATUSで正確な統計情報を提供していないことを認めています。 MYISAMテーブルは特に、行数などのメタデータの内部キャッシュを保持しますが、InnoDBエンジンはテーブルデータとインデックスを*/var/lib/mysql/ibdataに格納します**

InnoDBには便利なインデックスファイルはありません行番号をすばやく照会することができます。

InnoDBはテーブルデータ(*/var/lib/mysql/ibdata **)の範囲をサンプリングして動的に 'Rows'値を推定してから、およその数を外挿するので、SHOW TABLE STATUSによって報告されます。行。そんなにSHOW TABLE STATUS

MySQLのドキュメントを使用した場合のInnoDBドキュメントは最大で50%の行数の不正確さを認めるように、一致した行数のクエリを取得するには、MySQLのクエリキャッシュを使用しますが、ドキュメントは方法を指定しないでください示唆しています。これをどのように行うことができるかの簡潔な説明が続く。

まず、そのクエリキャッシュが有効になっているチェック:

mysql> SHOW VARIABLES LIKE 'have_query_cache'; 

have_query_cacheの値は、その後な/etc/my.cnf に次の行を追加することによって、クエリキャッシュを有効にNOある場合mysqldを再起動します。

have_query_cache=1 # added 2017 08 24 wh 
query_cache_size = 1048576 
query_cache_type = 1 
query_cache_limit = 1048576 

(詳細はhttp://dev.mysql.com/doc/refman/5.1/en/query-cache.htmlを参照)

クエリ

mysql> SHOW STATUS LIKE 'Qcache%'; 

とキャッシュの内容は、今SELECTクエリでSQL_CALC_FOUND_ROWSステートメントを使用します。

SELECT SQL_CALC_FOUND_ROWS COUNT(*) FROM my_innodb_table 

SQL_CALC_FOUND_ROWS試行するキャッシュからの読み取りを行い、このクエリが見つからない場合は、指定されたテーブルに対してクエリを実行し、次にテーブルの行数をクエリキャッシュにコミットします。上記のクエリ(または他の 'キャッシュ可能な' SELECTステートメント - 以下を参照)をさらに実行すると、キャッシュを参照して正しい結果を返します。'cachable' SELECT queries

その後 - 彼らは結果をLIMIT場合でも - クエリキャッシュに相談し、あなたが取得できるようになります(一度オフのみ)以前のキャッシュされたクエリのが正しい返し

SELECT FOUND_ROWS(); 

との合計テーブルの行番号テーブル行合計。

+0

あなたはplzの統計情報を取得するためにクエリキャッシュを問い合わせることによって何を意味するか説明できますか?私はクエリキャッシュとその動作を理解していますが、ここではその妥当性を確認していません – carpii

+0

クエリキャッシュの使用方法を説明するために私の回答を編集しました – venzen

3

テーブル内の行数を含む正確な統計情報を保持しない理由は、InnoDBがトランザクションを提供するために利用する行のマルチバージョン化です。実際の行数は実際にはトランザクションの分離レベルに依存します(コミットされていないトランザクションでレコードが削除または挿入されている可能性があります)、トランザクションが異なる分離レベルで実行される可能性があります。 'は、トランザクションが実行されていない場合にのみ、正しく応答される可能性があります。したがって、行またはデータ長のカウンタを保持することはほとんど不可能です。

読むよりおよそInnoDB restrictions

+0

SHOW TABLE STATUSを発行すると、 ?テーブルに影響を与える可能性のあるトランザクションはありませんが、値はまだ完全にランダムなようです。 – carpii

関連する問題