【发布时间】:2022-10-16 06:44:48
【问题描述】:
我有一个包含近十亿条记录的表,需要使用HAVING 对其进行查询。它非常慢(在体面的硬件上大约需要 15 分钟)。如何加快速度?
SELECT ((mean - 3.0E-4)/(stddev/sqrt(N))) as t, ttest.strategyid, mean, stddev, N,
kurtosis, strategies.strategyId
FROM ttest,strategies
WHERE ttest.strategyid=strategies.id AND dataset=3 AND patternclassid="1"
AND exitclassid="1" AND N>= 300 HAVING t>=1.8
我认为问题是t 不能被索引,因为它需要被计算。我无法将其添加为列,因为“3.0E-4”会因查询而异。
桌子:
create table ttest (
strategyid bigint,
patternclassid integer not null,
exitclassid integer not null,
dataset integer not null,
N integer,
mean double,
stddev double,
skewness double,
kurtosis double,
primary key (strategyid, dataset)
);
create index ti3 on ttest (mean);
create index ti4 on ttest (dataset,patternclassid,exitclassid,N);
create table strategies (
id bigint ,
strategyId varchar(500),
primary key(id),
unique key(strategyId)
);
explain select..:
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | SIMPLE | ttest | NULL | range | PRIMARY,ti4 | ti4 | 17 | NULL | 1910344 | 100.00 | Using index condition; Using MRR |
| 1 | SIMPLE | strategies | NULL | eq_ref | PRIMARY | PRIMARY | 8 | Jellyfish_test.ttest.strategyid | 1 | 100.00 | Using where |
【问题讨论】:
-
在子查询(或 cte)中做所有涉及 ttest 的事情,然后加入策略
-
如果你不介意,我需要更多帮助。我虽然这样做可以解决问题:
select ((mean-3.0E-4)/stddev/sqrt(N)), ttest.strategyid, mean, stddev, N, skewness, kurtosis, strategies.strategyId FROM ttest,strategies where ttest.strategyid=strategies.id AND dataset=3 AND patternclassid="1" AND exitclassid="1" AND N>= 300 and (select ((mean - 3.0E-4)/(stddev/sqrt(N))) from ttest) >1.8 ;不幸的是:错误 1242 (21000):子查询返回超过 1 行 -
为什么两个表中都有`strategyid,而不是你要加入的?
-
您遇到的错误是由于不必要的
SELECT。该表达式可以简单地用在WHERE子句中,(见我的回答。) -
CTE 是一种新奇的装饰,在这个案子。
标签: mysql performance query-optimization having