我有一个有2亿行的表,其中索引是在“created\u at”列中创建的,该列是datetime数据类型。
显示创建表[tablename]输出:
create table `table`
(`created_at` datetime NOT NULL)
PRIMARY KEY (`id`)
KEY `created_at_index` (`created_at`)
ENGINE=InnoDB AUTO_INCREMENT=208512112 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci'
创建时间范围为2020-04-01~2020-05-28。
我只想得到超过2020-05-15 23:00:00的行。
当我跑步时:
EXPLAIN SELECT created_at
FROM table
where created_at >= '2020-05-15 23:00:00';
它说它输出:
rows Extra
200mil Using Where
我的理解是,在rdms中,如果没有索引行没有排序,但是在列上创建索引时,它是按排序的,因此在找到'2020-05-15 23:00:00'之后,它只会返回之后的所有行。
另外,由于它的基数是7mil,我认为使用索引会比全表扫描更好。
是不是因为我输入了一个字符串?但当我尝试
where created_at >= date('2020-05-15 23:00:00');
还是一样。
和
where created_at >= datetime('2020-05-15 23:00:00');
输出语法错误。
mysql刚刚决定进行全表扫描更有效吗?
编辑:
使用等号
EXPLAIN SELECT created_at
FROM table
where created_at = '2020-05-15';
输出:
key_len ref rows Extra
5 const 51
在where子句中,如果我将字符串更改为date('2020-05-15'),它将输出:
key_len ref rows Extra
5 const 51 Using index condition
这是否意味着第一个相等的查询没有使用索引?
2条答案
按热度按时间q43xntqr1#
所有查询都将利用列上的索引
created_at
. mysql总是在匹配where
条款。您的输出
explain
s表示您没有这个索引,这是由您的create table
.只要创建索引,您的数据库就会使用它。
下面是一个演示:
eni9jsuy2#
如果值均匀分布,则大约25%的行
>= '2020-05-15 23:00:00'
是的,当您需要大量的表时,mysql会更喜欢全表扫描而不是使用索引。看看为什么mysql不总是使用索引进行选择查询?
在一个
DATE
背景,date('2020-05-15 23:00:00')
与相同'2020-05-15'
.在一个
DATETIME
背景,datetime('2020-05-15 23:00:00')
与相同'2020-05-15 23:00:00'
.Using index
意味着INDEX
是“covering”,这意味着整个查询可以完全在索引的btree中执行,而不必访问数据的btree。Using index condition
这意味着一些完全不同的东西——它与mysql设计中的两层(“处理程序”和“引擎”)相关的一个小优化有关(更多细节请参见“icp”又名“索引条件下推”。)