我在寻找原因和建议。我的表有大约140万行,当我运行下面的查询时,它花费了3分钟。为了显示结果,我加了count。我真正的疑问是不计其数的。
MariaDB [ams]> SELECT count(asin) FROM asins where asins.is_active = 1
and asins.title is null and asins.updated < '2018-10-28' order by sortorder,id;
+-------------+
| count(asin) |
+-------------+
| 187930 |
+-------------+
1 row in set (3 min 34.34 sec)
结构
id int(9) Primary
asin varchar(25) UNIQUE
is_active int(1) Index
sortorder int(9) Index
如果你需要更多的信息,请告诉我。提前谢谢。
用explain编辑查询
mariadb[ams]>explain select asin from asins where asins.is_active=1 and asins.title is null and asins.updated<'2018-10-28'order by sortorder,id;
4条答案
按热度按时间ifmq2ha21#
您的索引似乎处于活动状态并已更新。所以索引将被扫描(就像表扫描一样,索引中的每条记录都被读取),但是由于标题不在索引中,因此将有第二个操作在表中查找标题。您可以将其视为索引和表之间的连接。如果索引中的大多数记录都符合您的条件,那么连接将涉及表中的大部分数据。大连接速度慢。
如果针对索引的条件将导致返回大量记录,则最好进行全表扫描。
看到了吗https://dba.stackexchange.com/questions/110707/how-can-i-force-mysql-to-ignore-all-indexes 一种强制全表扫描的方法。试试看你的查询速度是否更快。
ix0qys7i2#
数据库正在扫描所有行以回答查询。我想你有一张很大的table。
对于此查询
ORDER BY
不必要(但不应影响性能:然后你需要一个索引
(is_active, title, updated)
.6l7fqoea3#
创建复合索引时,如果其中一部分是基于范围的,则首先需要基于范围的部分。
因此,请尝试索引(已更新,是否处于活动状态,标题)
这种方式更新成为前缀,可以在范围查询中使用。
oalqel3c4#
试试这些:
请提供
SHOW CREATE TABLE
.对于这些索引中的第一个,将进行一些筛选,但之后仍需对结果进行排序。
对于第二个索引,优化器可以选择只在
=
列,然后通过启动ORDER BY
. 风险在于,它仍将遭遇如此多的争吵,以至于避免这样的争吵是不值得的。表中有多少百分比
is_active = 1
? 什么百分比有空值title
? 那个日期范围内的百分比是多少?