0

この単純な MySQL クエリに問題があります。

select sender as id from message where status=1 and recipient=1

送信者テーブルには数百万行あります。

これを SequelPro で実行すると、最初は非常に遅く (~4 秒以上)、次の実行では非常に速く (~0.018 秒) 実行されます。ただし、数分後にもう一度実行すると、同じことが再び行われます。

SQL_NO_CACHE を使用しようとしましたが、それでも同じ結果が得られます。

DB エンジンは innoDB、DB は MySQL Percona XtraDB クラスターです。説明結果は次のとおりです。

|id|select_type|table  |type|possible_keys         |key |key_len|ref            |row   |Extra
| 1|SIMPLE     |message|ref |recipient,status, sent|sent|12     |const,const    |2989   |NULL

「送信済み」は、(受信者、ステータス) の複数列のインデックスです。誰でもこの問題を解決する考えがありますか?

ありがとうございました。

追加(コメントから)

CREATE TABLE 'message' (
    'id' int(20) NOT NULL AUTO_INCREMENT, 
    'sender' bigint(20) NOT NULL, 
    'recipient' bigint(20) NOT NULL, 
    'status' int(5) NOT NULL, 
    'date' timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 
    PRIMARY KEY ('id'), 
    KEY 'id' ('id'), 
    KEY 'recipient' ('recipient'), 
    KEY 'sender' ('sender'), 
    KEY 'date' ('date'), 
    KEY 'status' ('status'), 
    KEY 'sent' ('status','recipient')
) ENGINE=InnoDB AUTO_INCREMENT=90224500 DEFAULT CHARSET=latin1;
4

1 に答える 1

1

これらの症状は、キャッシングの問題を示しています。「クエリ キャッシュ」ではなく、エンジンのキャッシュのことです。

テーブルの大きさは?すべてのアクティブなテーブルの大きさは?

の値はinnodb_buffer_pool_size?

buffer_pool はテーブルよりもはるかに小さく、多くの処理が行われていると思われます。そのため、クエリのブロックが RAM から追い出され、元に戻すには数十回の読み取りが必要になります。

innodb_buffer_pool_size使用可能な RAM の約 70% に設定する必要があります。

詳細(に基づくCREATE TABLE)

「カバー」INDEX(status, recipient, sender)は高速になります。データにバウンスする必要はありません。クエリは完全にインデックス内で実行できます。

APRIMARY KEYはキーであるため、INDEX(id)冗長であり、DROPped.

別のKEYキーのプレフィックスである a は冗長です。私は(status)あなたの現在のCREATE TABLE.

于 2016-03-11T04:45:56.973 に答える