我真的很想知道为什么我的索引不工作。
我有两个表post, post_log.
create table post
(
id int auto_increment
primary key,
comment int null,
is_used tinyint(1) default 1 not null,
is_deleted tinyint(1) default 0 not null
);
create table post_log
(
id int auto_increment
primary key,
post_id int not null,
created_at datetime not null,
user int null,
constraint post_log_post_id_fk
foreign key (post_id) references post (id)
);
create index post_log_created_at_index
on post_log (created_at);
当我在下面查询时,created_at索引运行良好。
explain
SELECT *
FROM post p
INNER JOIN post_log pl ON p.id = pl.post_id
WHERE pl.created_at > DATE('2022-06-01')
AND pl.created_at < DATE('2022-06-08')
AND p.is_used is TRUE
AND p.is_deleted is FALSE;
当我在下面查询时,它不工作,post表做完整扫描。
explain
SELECT *
FROM post p
INNER JOIN post_log pl ON p.id = pl.post_id
WHERE pl.created_at > DATE('2022-06-01')
AND pl.created_at < DATE('2022-06-08')
AND p.is_used = 1
AND p.is_deleted = 0;
explain
SELECT *
FROM post p
INNER JOIN post_log pl ON p.id = pl.post_id
WHERE pl.created_at > DATE('2022-06-01')
AND pl.created_at < DATE('2022-06-08')
and p.comment = 111
"tinyint = 1"one_answers"tinyint is true"有什么不同?
和,为什么第一个查询工作正常,而其他不正常工作??
在制定查询计划时,MySQL必须决定是先使用索引筛选post_log
表,还是先使用is_used
和is_deleted
列筛选post
表。
= 1
测试特定值1
,而IS TRUE
对任何非零值为真。我猜它决定当你搜索特定的值时,首先过滤post
表会更有效,因为可能会有更少的匹配(因为这些列没有索引,它不知道0
和1
是唯一的值)。