如何利用索引删除mysql上的多行

xbp102n0  于 2021-06-20  发布在  Mysql
关注(0)|答案(1)|浏览(310)

我的表有大约9m行,我想删除大约270k行。我有一个sql,但不能利用我的索引,所以它在资源失败。
我每天有多行(创建于),用于每个exchange/base\u currency/quote\u currency对。
我的列是:

  1. Id exchange base_currency quote_currency created_at

我的索引是:

  1. ix1 id
  2. Ix2 exchange base_currency quote_currency created_at

对于每个exchange/base\u currency/quote\u currency对,我希望保留当天的最新行(最新id或创建时间)。因此,我找到了每天/exchange/base\u currency/quote\u currency的所有max(id),然后尝试删除所有未选中(不在中)的行。
我的问题是:

  1. DELETE FROM `tickers`
  2. WHERE
  3. DATE(`created_at`) = '2018-06-26'
  4. AND id NOT IN
  5. (SELECT MAX(id) FROM (select * FROM `tickers`) as t2
  6. WHERE DATE(`created_at`) = '2018-06-26'
  7. GROUP BY
  8. exchange
  9. , base_currency
  10. , quote_currency
  11. , DATE(created_at)
  12. )

selectmax(id)使用了ix2索引,因为groupby,但是我认为delete做了一个tablescan来提取带有日期的行( created_at )='2018-06-26',这是缓慢的。
有没有什么方法来构造这个查询以便我在delete上也使用ix2索引?或者我应该只在创建的\上创建另一个索引吗?

gopyfrb3

gopyfrb31#

为了使用索引,您需要做两件事:
为创建索引 created_at :

  1. create index ix3 on `tickers` (`created_at`);

避免在where条件下使用公式。例如,使用 between 取而代之的是:

  1. DELETE FROM `tickers`
  2. WHERE
  3. `created_at` between '2018-06-26T00:00:00' and '2018-06-26T23:59:59'
  4. AND id NOT IN
  5. (SELECT MAX(id) FROM (select * FROM `tickers`) as t2
  6. WHERE DATE(`created_at`) = '2018-06-26'
  7. GROUP BY
  8. exchange
  9. , base_currency
  10. , quote_currency
  11. , DATE(created_at)
  12. )

但是,您正在删除表的一个重要百分比(3%?)。当发生这种情况时,数据库引擎可能会忽略索引,而不管怎样,它还是更喜欢全表扫描。
您需要测试并查看数据库的用途。

展开查看全部

相关问题