如何在 MySQL 中使用 LAST_DAY() 以便不丢失索引优势?

How to use LAST_DAY() in MySQL so index advantage is not lost?

我正在使用 MySQL tables。

示例 table EMPprimary_key(EID, DOJ) 上):

ENAME EID DEPT SAL DOJ (YYYY-MM-DD)
A 6 ee 2000 2021-03-01
B 5 me 2020 2021-04-30
C 3 it 2000 2020-12-27
D 4 cv 2020 2020-10-31
E 1 it 2000 2021-01-01
F 2 it null 2021-02-28
G 7 ee null 2020-11-20

我有一项工作是将数据删除和插入到类似结构的 table。

进程需要删除非每月数据。也就是说,它将删除带有 EID 的行 6, 3, 1, 7:这些行有 DOJ 不是 月末

我提出的查询:

-- DOJ is of type DATE
DELETE FROM EMP WHERE LAST_DAY(DOJ) <> DOJ ;

它按预期工作。但是,因为有大量数据(~500 万),所以速度很慢。

我明白因为 LAST_DAY() 功能,我 loosing index 优势 DOJ。 您能否建议我如何改进查询?

Where (month(doj) in (9,4,6,11) and day(doj) <> 30) or
      (month(doj) in (1,3,5,7,8,10,12) and day(doj) <> 31) or
      (month(doj) in (2) and day(doj) not in(28,29))

?你可以稍微调整一下二月

关于索引,你是对的。在这里没有用。想到的唯一想法是生成一个列来告诉您日期是否是月底。因此,您将拥有一个可以索引并在查询中使用的列:

create table emp 
(
  ename varchar(100),
  ...
  doj date,
  is_month_end bool as (doj = last_day(doj))
);

create index idx_month_ends on emp (is_month_end);

delete from emp where not is_month_end;

演示:https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=397388b70bb1f459bbefce630ad27ac4

索引只能提供帮助,但是,如果这只是 table 中数据的很小一部分,比如说 1%。要删除更多行,阅读整个 table.

更有意义