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

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

我有一台mariadb 10.3服务器,下表(使用innodb存储引擎):

  1. create table if not exists token (
  2. `token` bigint unsigned not null,
  3. `uid` smallint unsigned not null default 0,
  4. `nham` int default 0,
  5. `nspam` int default 0,
  6. `timestamp` int unsigned default 0
  7. ) Engine=InnoDB;
  8. create index token_idx1 on token(token);
  9. create index token_idx2 on token(uid);

token表有900k行,我想用表中的2-300个数字执行以下查询 IN ( ) 条款:

  1. select token, nham, nspam from token where token in (1,2,3,4,...);

现在的问题是:查询的执行速度非常慢,而且无法使用 token_idx1 :

  1. +------+-------------+-------+------+---------------+------------+---------+-------+--------+-------------+
  2. | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
  3. +------+-------------+-------+------+---------------+------------+---------+-------+--------+-------------+
  4. | 1 | SIMPLE | token | ref | token_idx1 | token_idx1 | 2 | const | 837534 | Using where |
  5. +------+-------------+-------+------+---------------+------------+---------+-------+--------+-------------+

由于标记列被编入索引,我很惊讶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并用

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

相关问题