web-dev-qa-db-ja.com

タイムスタンプインデックスの不適切な使用

小さなテーブル(約2 Mの行、5つのクラシック列、id、description、title、created_at、座標(ポイント))でWHERE created_at BETWEEN ... AND ... ORDER BY created_at LIMIT 50を実行すると、非常に遅くなります(約15秒)

created_atはインデックス付きのtimestampです。

しかし、EXPLAINを使用すると、フィルターされた列に10と表示されますが、これは悪いことです。この10の原因は何でしょうか?

クエリはシンプル、テーブルはinnodb、パーティションなし

SELECT * FROM posts 
WHERE created_at BETWEEN '2016-10-28 18:25:00' 
                     AND '2016-11-02 18:25:00' 
ORDER BY created_at DESC 
LIMIT 50;

計画を説明する

1   SIMPLE  posts   NULL    range   created_at  created_at  5   NULL    5317    10.00   Using index condition; Using where

MySQL 5.7クラスターバージョン

(コメントから追加)

CREATE TABLE posts (
    id int(11) unsigned NOT NULL, 
    title varchar(120) NOT NULL DEFAULT '', 
    description text NOT NULL, 
    created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    status tinyint(4) NOT NULL DEFAULT '1', 
    context tinyint(4) NOT NULL DEFAULT '0', 
    coordinates point DEFAULT NULL, 
    PRIMARY KEY (id), 
    KEY created_at (created_at), 
    KEY status (status), 
    KEY context (context)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2
Zoé R.

EXPLAINは、最高の状態です。 「範囲」はWHEREに適しています。 ORDER BYは言及されていませんが、同様に処理する必要があります。そして、それは50で止まるはずです(ここでも、EXPLAINには手掛かりがありません)。

10.00表のパーセントは、実質的に情報に基づいていない推定値です。それを無視します。

「5.7クラスタ化」は矛盾です。 「NDB Cluster」という意味ですか?それともGaleraベースのクラスターですか?

フラグのインデックス付け(status)は通常役に立たない。

indexing の詳細。

15秒の質問に戻ります。時間は不当に長いことに同意します。ここにいくつかの部分的な説明があります...

  • 他の何かがシステムでビジーでした。
  • かさばるTEXT列はオフレコで保管されていたため、追加のディスクヒットが必要でした。確かに、50回のディスクヒットは1秒もかかりません。
  • 投稿は散らばっているかもしれません。つまり、連続して保存されません。繰り返しになりますが、おそらく50回のディスクヒットと1秒未満です。

キャッシュされていないブロックを許可した後でも、1秒以上かかったことに驚いています。

クエリをもう一度実行します(キャッシュを無効にするため)。それはどのくらいかかりますか?

チェックすべきもう1つのこと-innodb_buffer_pool_sizeおよびRAMのサイズはどれくらいですか?小さなVMが問題のpartである可能性があります。swapが発生するほど大きいbuffer_poolは、実際には15秒を説明できます。

1
Rick James