mysql 8.0 Windows 版本。
有这么一个股市行情表:##
tb_quote (
op_date ,
code ,
price ,
ratio ,
hsl ,
index unique idx_1 (op_date,code) ,
index idx_2(code)
)
每个交易日 6000 条,一年几百万条规模。
现在有一个简单需求:##
- 筛选某一天涨幅在( 3%,5%)区间的股票,且换手率在( 5%-10%)区间之间
- 查看后一天的股票涨跌情况。
实现语句很简单:
方案一: 第一条语句在 1 秒内返回结果:(20 条记录)
select code from tb_quote where op_date='yyyy-mm-dd' and ratio >3 and ratio <5 and hsl>5 and hsl <10
嵌套第二条后:
select a.* from tb_quote a join (
select code from tb_quote b where op_date='yyyy-mm-d1' and ratio >3 and ratio <5 and hsl>5 and hsl <10 ) t
on a.code=t.code and a.op_date='yyyy-mm-d2'
执行时间就超过 1 分钟!
** 查看 mysql 解释: **
- simple b,key idx_1 ,key_len=3,ref=const ,rows=s5373,filterd 0.05, Extra:using where
- simple a, key idx_2, key_len=30, ref=tb_quote.code, rows=465 ,filtered 0.21, Extra:using where
** 方案二: ** 但是如果把第一条语句的结果保存在一个表 tmp 里面,并且 code 建立普通索引以后,变成:
select a.* from tb_quote a join (
select code from tmp ) t
on a.code=t.codeand a.op_date='yyyy-mm-d3'
执行时间不超过 1 秒!!!
** 查看 mysql 解释:**
- simple a, key idx_1, key_len=3, ref=const, rows=5365 ,filtered 100, Extra:useing where
- simple tmp, key idx_code ,key_len=29,ref=a.f12 ,rows=1, filterd 100, Extra:using where
发现差别在:
- 次序不同,方案二子表 tmp 在前,方案一子表 b 在后;
- filtered 值不同,方案二是 100 ,方案一只有 0.05 ;
不知道 mysql 是怎么优化的?如果不用中间表过渡的话,应该怎么写 sql ?