为什么 MySQL 不在此查询中使用我的索引?
Why does MySQL not use my index in this query?
创建 table 语句:
create table stock_master.turnover_rate_trade
(
id int auto_increment
constraint `PRIMARY`
primary key,
before_day int null,
pre_day int null,
turnover_rate double null ,
max_rise double null ,
keep_day int null ,
code varchar(50) null ,
date date null ,
real_keep int null ,
rate double null ,
create_time timestamp default CURRENT_TIMESTAMP null,
update_time timestamp default CURRENT_TIMESTAMP null,
constraint uindex
unique (before_day, pre_day, turnover_rate, max_rise, keep_day, code, date)
);
我的select声明:
select id,
before_day,
pre_day,
turnover_rate,
max_rise,
keep_day,
code,
date
real_keep,
rate,
create_time,
update_time
from turnover_rate_trade
where
before_day=6 and pre_day =3 and turnover_rate=22.1 and max_rise =7.1 and keep_day=5 and
code='100000' and date='2022-02-02'
执行计划:
本人非专业dba,尽量避免索引失效
条件里写的很清楚,就是不行
table数据信息:
rows: 2 hundred million
before_day: 5~29
pre_day: 0~4
keep_day: 0~29
turnover_rate: 1~23
max_rise: 1~29
分布均匀
建议:
我花了一个多小时来删除和重建索引。
create index turnover
on turnover_rate_trade (before_day, pre_day, turnover_rate, max_rise, keep_day, code, date)
现在可以了!有人可以解释一下吗?
FLOAT
或DOUBLE
为近似值,以二进制形式存储。 22.1
是一个十进制值,无法精确存储在任何 DOUBLE
中。用一侧 DOUBLE
和另一侧 non-integral 十进制数字 =
进行测试是有风险的。
我明白这无法解释为什么索引(根据 EXPLAIN
)没有被使用。但是让我们先修复比较。
方案A:使用某种形式的范围测试。 (使用索引肯定会搞砸。)
方案 B:将列切换为 DECIMAL
。 (这样的ALTER
会花很长时间。)
这里可能有错别字:
code,
date -- perhaps you wanted a comma?
real_keep,
另一个问题...您没有指定 PRIMARY KEY
(并且 UNIQUE
键由于其大部分列的可空性而无法提升为 PK)。真的是所有表都需要一个PK
建议在适当的地方制作专栏NOT NULL
。
建议添加显式 PK。
(同样,我无法向您的索引解释失败。)
创建 table 语句:
create table stock_master.turnover_rate_trade
(
id int auto_increment
constraint `PRIMARY`
primary key,
before_day int null,
pre_day int null,
turnover_rate double null ,
max_rise double null ,
keep_day int null ,
code varchar(50) null ,
date date null ,
real_keep int null ,
rate double null ,
create_time timestamp default CURRENT_TIMESTAMP null,
update_time timestamp default CURRENT_TIMESTAMP null,
constraint uindex
unique (before_day, pre_day, turnover_rate, max_rise, keep_day, code, date)
);
我的select声明:
select id,
before_day,
pre_day,
turnover_rate,
max_rise,
keep_day,
code,
date
real_keep,
rate,
create_time,
update_time
from turnover_rate_trade
where
before_day=6 and pre_day =3 and turnover_rate=22.1 and max_rise =7.1 and keep_day=5 and
code='100000' and date='2022-02-02'
执行计划:
本人非专业dba,尽量避免索引失效
条件里写的很清楚,就是不行
table数据信息:
rows: 2 hundred million
before_day: 5~29
pre_day: 0~4
keep_day: 0~29
turnover_rate: 1~23
max_rise: 1~29
分布均匀
建议:
我花了一个多小时来删除和重建索引。
create index turnover
on turnover_rate_trade (before_day, pre_day, turnover_rate, max_rise, keep_day, code, date)
现在可以了!有人可以解释一下吗?
FLOAT
或DOUBLE
为近似值,以二进制形式存储。 22.1
是一个十进制值,无法精确存储在任何 DOUBLE
中。用一侧 DOUBLE
和另一侧 non-integral 十进制数字 =
进行测试是有风险的。
我明白这无法解释为什么索引(根据 EXPLAIN
)没有被使用。但是让我们先修复比较。
方案A:使用某种形式的范围测试。 (使用索引肯定会搞砸。)
方案 B:将列切换为 DECIMAL
。 (这样的ALTER
会花很长时间。)
这里可能有错别字:
code,
date -- perhaps you wanted a comma?
real_keep,
另一个问题...您没有指定 PRIMARY KEY
(并且 UNIQUE
键由于其大部分列的可空性而无法提升为 PK)。真的是所有表都需要一个PK
建议在适当的地方制作专栏NOT NULL
。
建议添加显式 PK。
(同样,我无法向您的索引解释失败。)