我有一台mariadb 10.3服务器,下表(使用innodb存储引擎):
create table if not exists token (
`token` bigint unsigned not null,
`uid` smallint unsigned not null default 0,
`nham` int default 0,
`nspam` int default 0,
`timestamp` int unsigned default 0
) Engine=InnoDB;
create index token_idx1 on token(token);
create index token_idx2 on token(uid);
token表有900k行,我想用表中的2-300个数字执行以下查询 IN ( )
条款:
select token, nham, nspam from token where token in (1,2,3,4,...);
现在的问题是:查询的执行速度非常慢,而且无法使用 token_idx1
:
+------+-------------+-------+------+---------------+------------+---------+-------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+------+---------------+------------+---------+-------+--------+-------------+
| 1 | SIMPLE | token | ref | token_idx1 | token_idx1 | 2 | const | 837534 | Using where |
+------+-------------+-------+------+---------------+------------+---------+-------+--------+-------------+
由于标记列被编入索引,我很惊讶explain select说优化器对它没有兴趣 token_idx1
(而且查询需要很长的时间,由于全表扫描,大约需要30秒)。
如何解决这个问题?我知道我可以用 INDEX(token_idx1)
在查询中,但我会解决它没有这样的黑客。
2条答案
按热度按时间eiee3dmh1#
解决方法是重写查询。因此,虽然这样的查询在性能上很糟糕:
从token中选择token、nham、nspam,其中token在(1,2,3,4,…);
下面的查询速度很快(即使表中不存在某些标记值):
从token=1或token=2或token=3或…,选择token、nham、nspam。。。;
所以问题解决了,尽管我仍然不明白为什么优化器在第一次查询时很困难。
不管怎样,感谢您的所有想法、想法和贡献,让我找到解决方法。
cnh2zyt32#
删除现有的索引标记\u idx1并用