0

結合しようとしている 4 つのテーブルがあり、結果を新しいテーブルに出力します。私のコードは次のようになります。

create table tbl  
select a.dte, a.permno, (ret - rf) f0_xs_ret, (xs_ret - (betav*xs_mkt)) f0_resid, mkt_cap     last_year_mkt_cap, betav beta_value
from a inner join b using (dte)
inner join c on (year(a.dte) = c.yr and a.permno = c.permno)
inner join  d on (a.permno = d.permno and year(a.dte)-1 = year(d.dte));

すべてのテーブルには複数のインデックスがあり、 tableのa場合は一意のレコードを(dte, permno)識別し、 tableのb場合はdteid が一意のレコード、 table のc場合は(yr, permno)id が一意のレコード、 tabledの場合は id が一意のレコードを識別します(dte, permno)selectクエリの部分からの説明は次のとおりです。

+----+-------------+-------+--------+-------------------+---------+---------+----------    ------------------------+--------+-------------------+
| id | select_type | table | type   | possible_keys     | key     | key_len | ref                                  | rows   | Extra             |
+----+-------------+-------+--------+-------------------+---------+---------+----------    ------------------------+--------+-------------------+
|  1 | SIMPLE      | d     | ALL    | idx1              | NULL    | NULL    | NULL                                 | 264129 |                   | 
|  1 | SIMPLE      | c     | ref    | idx2              | idx2    | 4       |     achernya.d.permno                |     16 |                   | 
|  1 | SIMPLE      | b     | ALL    | PRIMARY,idx2      | NULL    | NULL    | NULL                                 |  12336 | Using join buffer | 
|  1 | SIMPLE      | a     | eq_ref | PRIMARY,idx1,idx2 | PRIMARY | 7       |    achernya.b.dte,achernya.d.permno |      1 | Using where       | 
+----+-------------+-------+--------+-------------------+---------+---------+----------------------------------+--------+-------------------+

なぜ mysql はこれを処理するために非常に多くの行を読まなければならないのでしょうか? これを正しく読んでいる場合、(264129*16*12336)行を読み取る必要があります。これには1か月かかります。

誰かがここで何が起こっているのか説明してもらえますか?

4

1 に答える 1

2

結合条件として関数を使用しているため、MySQL は行を読み取る必要があります。上のインデックスは、クエリのdte解決には役立ちません。YEAR(dte)これを高速化したい場合は、年を独自の列に入れて結合で使用し、インデックスをその列に移動します。これが非正規化を意味する場合でも。

関数を適用しないインデックス内の他の列については、インデックスがあまり利点を提供しない場合、またはそれらがインデックスの左端の列ではなく、結合条件のそのインデックスの左端のプレフィックス。

インデックスが利用可能であっても、MySQL がインデックスを使用しないことがあります。これが発生する状況の 1 つは、インデックスを使用するために MySQL がテーブル内の行の大部分にアクセスする必要があるとオプティマイザが推定した場合です。(この場合、必要なシークが少ないため、テーブル スキャンの方がはるかに高速になる可能性があります。)

http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html

于 2012-08-15T04:15:45.500 に答える