我的表有大约9M行,我想删除大约270K行。我有一个有效的SQL,但无法使用索引,因此在资源上失败。
对于每一对交易所/基准货币/报价货币对,我每天都有多行(created_at)。
我的专栏是:
Id exchange base_currency quote_currency created_at
我的索引是:
ix1 id
Ix2 exchange base_currency quote_currency created_at
对于每个交易所/基准货币/ quote_currency对,我想保留当天的最新行(最新ID或created_at)。因此,我找到了每天/交易所/ base_currency / quote_currency的所有MAX(id),然后尝试删除所有未选中的行(不输入)。
我的查询是:
DELETE FROM `tickers`
WHERE
DATE(`created_at`) = '2018-06-26'
AND id NOT IN
(SELECT MAX(id) FROM (select * FROM `tickers`) as t2
WHERE DATE(`created_at`) = '2018-06-26'
GROUP BY
exchange
, base_currency
, quote_currency
, DATE(created_at)
)
由于GROUP BY,SELECT MAX(id)使用ix2索引,但是我认为DELETE进行表扫描以使用DATE(created_at
)='2018-06-26 ',这很慢。
以任何方式构造此查询,因此我也使用DELETE上的ix2索引吗?还是应该仅在created_at上创建另一个索引?
答案 0 :(得分:1)
要使用索引,您需要做两件事:
为created_at
创建索引:
create index ix3 on `tickers` (`created_at`);
请通过措辞避免对where条件使用公式。例如,改用between
:
DELETE FROM `tickers`
WHERE
`created_at` between '2018-06-26T00:00:00' and '2018-06-26T23:59:59'
AND id NOT IN
(SELECT MAX(id) FROM (select * FROM `tickers`) as t2
WHERE DATE(`created_at`) = '2018-06-26'
GROUP BY
exchange
, base_currency
, quote_currency
, DATE(created_at)
)
但是,您要删除表的重要百分比(3%?)。发生这种情况时,数据库引擎可能会忽略索引,而仍然希望进行全表扫描。
您需要测试并查看数据库的用途。