MySQLマルチカラムインデックスが機能していません(予想どおり)?
-
10-10-2019 - |
質問
私はこのようなテーブルを持っています
CREATE TABLE IF NOT EXISTS `tbl_folder` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`owner_userid` int(11) NOT NULL,
`name` varchar(63) NOT NULL,
`description` text NOT NULL,
`visibility` tinyint(4) NOT NULL DEFAULT '2',
`num_items` int(11) NOT NULL DEFAULT '0',
`num_subscribers` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `owner_userid` (`owner_userid`),
KEY `vis_sub_item` (`visibility`,`num_subscribers`,`num_items`)
) ENGINE=InnoDB
可視性、num_subscribers、num_itemsに関するインデックスがあるため、最初の15行だけを調べる必要があると予想されます。何か案が?ありがとう
EXPLAIN SELECT t.id, name, description, owner_userid, num_items, num_subscribers
FROM `tbl_folder` `t`
WHERE visibility =2
ORDER BY `t`.`num_subscribers` DESC , `t`.`num_items` DESC
LIMIT 15
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t ref vis_sub_item vis_sub_item 1 const 55856 Using where
解決
3フィールドインデックスはよさそうです EXPLAIN
有望です。
「55856行」と書かれていますが、それは単なる 見積もり によって提供された EXPLAIN
.
以来 key_len =1
, 、あなたはそれがあなたの複合指数の最初のバイトを平等/参照として使用していることを知っています。
あなたに言及されたfilesortがないので Extra
フィールド、あなたはそれを知っています ORDER BY
/並べ替え は インデックスによって処理されています。
あなたがあなたをチェックするなら handler_%
セッションの統計では、実際に読まれている行の数をよりよく理解できます。
副考え:
あなたは最終的にあなたの行を取得するためにディスクを押していると知っているので、あなたのデータの99%が持っている場合、 visibility=2
(推測するだけです)、あなたはおそらく、単なる複合インデックスを使用して等しく良い/高速な結果を得るでしょう num_subscribers
& num_items
. 。または、単一のインデックスがある場合、間違いなく良い/高速 num_subscribers
, 、それに応じて、それはカーディナリティ/ユニークさです。
他のヒント
私はそうは思わない EXPLAIN
を見てください OFFSET
また LIMIT
句。 EXPLAIN
クエリの実行方法、使用したキー、テーブルの結合方法などを示すことになっています。 LIMIT
節は、ポストクエリ修飾子のようなものです...今、私たちが望むものを知っているので、最初の多くの人だけを与えます。したがって、行フィールドには、クエリに存在する可能な行の数が含まれています。そこから、 OFFSET
と LIMIT
必要な特定のものを選択します。
あなたがあなたを実行した場合、私はそれを考えています SELECT
それなし EXPLAIN
, 、あなたが望むレコードの数を取得するでしょう。
はい、問題はあなたのインデックスが正しくないことです。つまり、3つの3つのフィールドをインデックス化し、選択クエリのみが1つのみをチェックしました。 MySQLのインデックス作成では、2行が個別に3行のインデックス作成とは異なります。
試す
CREATE TABLE IF NOT EXISTS `tbl_folder` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`owner_userid` int(11) NOT NULL,
`name` varchar(63) NOT NULL,
`description` text NOT NULL,
`visibility` tinyint(4) NOT NULL DEFAULT '2',
`num_items` int(11) NOT NULL DEFAULT '0',
`num_subscribers` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `owner_userid` (`owner_userid`),
KEY `vis_index` (`visibility`),
KEY `vis_sub_item` (`num_subscribers`,`num_items`)
) ENGINE=InnoDB