小さなテーブル(約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;
EXPLAIN
は、最高の状態です。 「範囲」はWHERE
に適しています。 ORDER BY
は言及されていませんが、同様に処理する必要があります。そして、それは50で止まるはずです(ここでも、EXPLAIN
には手掛かりがありません)。
10.00
表のパーセントは、実質的に情報に基づいていない推定値です。それを無視します。
「5.7クラスタ化」は矛盾です。 「NDB Cluster」という意味ですか?それともGaleraベースのクラスターですか?
フラグのインデックス付け(status)
は通常役に立たない。
indexing の詳細。
15秒の質問に戻ります。時間は不当に長いことに同意します。ここにいくつかの部分的な説明があります...
TEXT
列はオフレコで保管されていたため、追加のディスクヒットが必要でした。確かに、50回のディスクヒットは1秒もかかりません。キャッシュされていないブロックを許可した後でも、1秒以上かかったことに驚いています。
クエリをもう一度実行します(キャッシュを無効にするため)。それはどのくらいかかりますか?
チェックすべきもう1つのこと-innodb_buffer_pool_size
およびRAMのサイズはどれくらいですか?小さなVMが問題のpartである可能性があります。swapが発生するほど大きいbuffer_poolは、実際には15秒を説明できます。