我正在尝试连接四个表并将结果输出到新表。我的代码如下所示:
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));
所有表都有多个索引,对于表a
,(dte, permno)
为表b
标识唯一记录,dte
id是表{的唯一记录{1}},c
ID为唯一记录,对于表(yr, permno)
,d
为唯一记录。查询的(dte, permno)
部分的解释是:
select
为什么mysql必须读取这么多行来处理这个东西?如果我正确读到这个,它必须阅读+----+-------------+-------+--------+-------------------+---------+---------+---------- ------------------------+--------+-------------------+
| 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 |
+----+-------------+-------+--------+-------------------+---------+---------+----------------------------------+--------+-------------------+
行,这应该是一个好月份。
有人可以解释一下这里发生了什么吗?
答案 0 :(得分:2)
MySQL必须读取行,因为您使用函数作为连接条件。 dte
上的索引无法解决查询中的YEAR(dte)
问题。如果你想快速实现这一点,那么将年份放在它自己的列中以在连接中使用并将索引移动到该列,即使这意味着一些非规范化。
对于索引中未应用函数的其他列,如果索引不会提供太多好处,或者它们不是索引中最左侧的列,则可能不会使用它们t在连接条件中使用该索引的最左前缀。
有时MySQL不使用索引,即使有索引也是如此。发生这种情况的一种情况是,优化器估计使用索引将需要MySQL访问表中非常大比例的行。 (在这种情况下,表扫描可能会快得多,因为它需要较少的搜索。)