mysql:15357
From: Mikiya Okuno <Mikiya Okuno <mikiya.okuno@xxxxxxxxxx>>
Date: Thu, 1 Jul 2010 15:57:34 +0900
Subject: [mysql 15357] Re: 検索条件カラムを縦持ちにした場合の検索の性能について。
奥野です。 独立したインデックスの場合、condテーブルが駆動表になれば問題ないんですが、 内部表になってしまうと結合のためにa_idインデックスを利用するため condインデックスが効きません。その場合、(a_id, cond1)というような 複合インデックスが必要になります。しかしそのようなインデックスしか存在しないと 今度はcond単体で検索することが出来なくなるため、それとは別に 独立したインデックスもやはり必要です。condごとに単体のインデックスと 複合インデックスをあわせもつのは、躊躇しますよね。 なぜこんな面倒なことになるかというと、MySQLではINTERSECTをサポートしていない からですね。(bug #31336)Index merge(intersect)という検索アルゴリズムが ありますが、このような範囲検索では効きません。 とりあえず、考えられる方策としては、 ・テーブルスキャン覚悟でJOINではなくANDで条件を結合させる。 ※JOINごとにスキャンが発生するよりは遙かにマシですね。 ・色々覚悟で体のインデックスと複合インデックスをあわせもつ。 ・condごとにテーブルを分ける。(どっちにしろインデックスは必要です。) ・サブクエリを利用する。(下記参照) サブクエリについては、condごとにかなり行数を絞り込めるようなら試して見る 価値があると思います。 SELECT a_id, o.val FROM a JOIN (SELECT a_id FROM cond WHERE cond1 BETWEEN 00110 AND 00120) AS c1 USING (a_id) JOIN (SELECT a_id FROM cond WHERE cond2 BETWEEN 00270 AND 00290) AS c2 USING (a_id) JOIN o USING (a_id); ではでは。 -- 奥野 幹也 http://www.google.com/profiles/mikiya.okuno http://nippondanji.blogspot.com/ http://twitter.com/nippondanji On 28/06/2010, at 11:35 PM, とみたまさひろ wrote: > とみたです。 > > On Mon, 28 Jun 2010 21:38:23 +0900 > MATSUNAGA Ichiro <vikke.bsd@xxxxxxxxxx> wrote: > >> この状態で、他のtable(other)をjoinしつつ、cond1(001)が10あるいは20、かつcond2(002)が70あるいは80あるいは90の条件を見たすrecordが欲しい場合、 >> select a_id, o.val >> from >> a >> inner join cond c1 using(a_id) >> inner join cond c2 using(a_id) >> inner join other o using(o_id) >> where >> c1.cond between 00110 and 00120 >> and c2.cond between 00270 and 00290; >> というsqlを実行してみたのですが、結構重い状態です。 > > 次のように cond カラムに独立したインデックスを張ってみてはいかがでしょうか。 > > create table cond ( > a_id int(10) not null, > cond int(5) not null, > primary key (a_id, cond), > index (cond) > ) > > -- > とみたまさひろ <tommy@xxxxxxxxxx> > 日本MySQLユーザ会 http://www.mysql.gr.jp >
@ 15349 2010-06-28 21:38 [MATSUNAGA Ichiro <vi] 検索条件カラムを縦持ちにした場合の検索の性能について。 @ 15350 2010-06-28 21:44 ┣[MATSUNAGA Ichiro <vi] 15351 2010-06-28 23:35 ┗[とみたまさひろ <tomm] -> 15357 2010-07-01 15:57 ┗[Mikiya Okuno <mikiya]