mysql:11280
From: Hirokazu Aoyama <Hirokazu Aoyama <aoyama@xxxxxxxxxx>>
Date: Sun, 27 Mar 2005 03:15:21 +0900
Subject: [mysql 11280] Re: selectで
青山です。 マニュアルにはあんまりまとまった記述がなさそうなので、 ついでなのでこのへんも。 # どちらかというとMySQLの話というよりRDBの一般的な話です。 # OracleやDB2やPostgreSQLをよく知っている人は特に読まなくても # よいと思います。 > KK@IBです > > > また、1個または数個のデータにアクセスしたい場合には常に > > ランダムアクセスの方が効率がよいのかというと、必ずしもそうではなく、 > > 行数に比べてキー値の種類が少ない列(=カーディナリティが低い列) > > については、検索結果データの絶対数とディスク上の分布によって、 > > どちらの方法が速いのかが変わってきます。 > > これは非常に重要な指摘ですね。 > 最速の検索は、データの内容によって変化します。 > 上記のような場合は、キーが意味をなさない状態です。 > 別のキーがない場合、同じキー値の中でシークエンシャルアクセスで > データを探す状態になりますから。 キーが意味をなさない、ということではなく、 検索条件に指定するキー値によって、インデックスの使用が適切だったり、 適切でなかったりする、という言い方が正しいでしょう。 インデックスを張っており、かつカーディナリティが低い列の例として、 例えば、値の大半が 1 で、まれに 0 が入っているような列(col_x)を考えます。 行数はある程度多い(数万とか数十万とか)ものとし、かつ、0の割合が 全体の数%くらいであると仮定します(ここが重要)。 この場合は、WHERE col_x = 1 という条件では、インデックスを使わずに FULL SCANする方が速いです。 一方、WHERE col_x = 0 という条件では、インデックスを使った方が 速いでしょう。 しかし、InnoDBの場合、mysqldは、col_xが2値しか持たず、かつ 0が少なくて1が多いということは知りません。 # [注意] MyISAMやBDBの場合は自動的に統計データが収集されるため、 # この記述は当てはまりません。 このため、実際には、WHERE col_x = 1 と指定した場合でも、DBは インデックスを使って検索しようとしてしまいます。 # [注意] これも、InnoDBの場合は、です。 # MyISAM,BDBの場合は、col_x = 1 と指定した場合は自動的に # インデックスを使わないFULL SCANを選択してくれます。 InnoDBは今のところコストベースのオプティマイザを持たないようなので、 (MySQLのサイトを見ると、開発予定も今のところなし?) 上記の問題を解決するにはヒントを使ってインデックスを強制的に 無視するように指示するしかありません。 SELECT * FROM table_name IGNORE INDEX (index_name_of_col_x) WHERE col_x = 1 このあたりについてはMySQLはまだまだ発展途上ですね。 普段コストベースオプティマイザにまかせて何気なくSQL文を 書いてしまっている人にはMySQLを使いこなすのは少々大変かもしれません。。 # まあ、基本的な性能が高いのでそれほど気にはならないかもしれませんが。 -- Hirokazu Aoyama <aoyama@xxxxxxxxxx>
11272 2005-03-26 01:58 [<hiromitsu.narimasu_] Re: selectで 11274 2005-03-26 10:49 ┗[Hirokazu Aoyama <aoy] 11275 2005-03-26 12:56 ┣[Hirokazu Aoyama <aoy] 11276 2005-03-26 16:12 ┃┗[深海水草 <VYG01106@x] 11277 2005-03-26 17:21 ┗["KKuji_Y2" <kkuji@xx] 11278 2005-03-26 19:35 ┣[Hirokazu Aoyama <aoy] 11281 2005-03-27 05:04 ┃┗["KKuji_Y2" <kkuji@xx] -> 11280 2005-03-27 03:15 ┗[Hirokazu Aoyama <aoy]