为什么mysql整数比较比datetime空比较慢?

hc2pp10m  于 2021-08-13  发布在  Java
关注(0)|答案(2)|浏览(410)

我正在使用MySQL5.7。
有一张table叫 transactions 有超过300万张唱片。表架构如下: id -int(自动递增) deleted_at (datetime,允许为空) record_status (tinyint,默认值为1)
与此表相关的其他列。。。
这个 record_status 是的整数版本 deleted_at . 删除记录时,该值设置为0。还会为此列创建索引。
基于null的datetime查询需要 740 ms 执行: select transactions.id from transactions where transactions.deleted_at is null 基于tinyint的查询 15.1 s 执行: select transactions.id from transactions where transactions.record_status = 1 对tinyint列(带索引)的检查不应该更快吗?为什么会这样?
[编辑]
添加了有关表性能的信息
为了进一步实验,所有不必要的列都从表中删除了。只有以下情况仍然存在。 id -int(自动递增) deleted_at (datetime,允许为空) record_status (tinyint,默认值为1) transaction_time (日期时间)
查询1:需要2.3ms

select transactions.id from transactions
where transactions.record_status = 1 limit 1000000;

查询2:需要2.1ms

select transactions.id from transactions 
where transactions.deleted_at is null limit 1000000;

查询3:需要20秒

select transactions.id from transactions 
where transactions.record_status = 1 
and transaction_time > '2020-04-01' limit 1000;

查询4:需要500毫秒

select transactions.id from transactions 
where transactions.deleted_at is null 
and transaction_time > '2020-04-01' limit 1000;

查询5:394ms

select transactions.id from transactions
where transaction_time > '2020-04-01' limit 1000000;

我不明白为什么查询3要花这么长时间。

a6b3iqyw

a6b3iqyw1#

通过增加一个综合指数来解决这个问题。
以下两种方法现在都可以提高性能。
复合键打开 transaction_time 以及 deleted_at .
复合键打开 transaction_time 以及 record_status .
多亏了@gordon linoff和@jarlh。他们的建议导致了这一发现。

q1qsirdb

q1qsirdb2#

select transactions.id from transactions 
where transactions.record_status = 1 
and transaction_time > '2020-04-01' limit 1000;

没有这样的复合索引就无法进行优化--按以下顺序:

INDEX(record_status, transaction_time)

(不,两个单独的单列索引将不起作用。)

相关问题