如何索引一个mysql innodb表来查询选择在何处输入(此处输入一些值)?

eyh26e7m  于 2021-06-20  发布在  Mysql
关注(0)|答案(2)|浏览(330)

我有一台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) 在查询中,但我会解决它没有这样的黑客。

eiee3dmh

eiee3dmh1#

解决方法是重写查询。因此,虽然这样的查询在性能上很糟糕:
从token中选择token、nham、nspam,其中token在(1,2,3,4,…);
下面的查询速度很快(即使表中不存在某些标记值):
从token=1或token=2或token=3或…,选择token、nham、nspam。。。;
所以问题解决了,尽管我仍然不明白为什么优化器在第一次查询时很困难。
不管怎样,感谢您的所有想法、想法和贡献,让我找到解决方法。

cnh2zyt3

cnh2zyt32#

删除现有的索引标记\u idx1并用

CREATE INDEX token_idx1 ON token(token) USING BTREE;
CREATE INDEX token_idx2 ON token(uid) USING BTREE;

相关问题