简体   繁体   English

MySql 优化器不使用 varchar 上的索引

[英]MySql optimizer doesn't use the index on varchar

I have a table defined as我有一个表定义为

CREATE TABLE `article` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `field1` varchar(1024) NOT NULL,
  `priority` int(11) NOT NULL,
  `prodcode` varchar(64) NOT NULL,
  `status` int(8) NOT NULL,
  `error` varchar(1024) DEFAULT NULL,
  `ctime` datetime DEFAULT CURRENT_TIMESTAMP,
  `mtime` datetime DEFAULT NULL,
  `event` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `article_prodcode_idx` (`prodcode`),
  KEY `article_status_idx` (`status`),
  KEY `article_priority_idx` (`priority`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

This table contains about 40 million of record.该表包含大约 4000 万条记录。 When I run a query like当我运行一个查询时

SELECT * FROM article WHERE prodcode='a-4536-x-bef45-green';

the optimizer "decides" that such query doesn't have to use any index (an "EXPLAIN SELECT..." results in a优化器“决定”这样的查询不必使用任何索引(“EXPLAIN SELECT...”导致

+----+-------------+----------+------+---------------+------+---------+------+----------+-------------+
| id | select_type | table    | type | possible_keys | key  | key_len | ref  | rows     | Extra       |
+----+-------------+----------+------+---------------+------+---------+------+----------+-------------+
|  1 | SIMPLE      | article  | ALL  | NULL          | NULL | NULL    | NULL | 39415251 | Using where |
+----+-------------+----------+------+---------------+------+---------+------+----------+-------------+

If I add eg another field like priority or status, the optimizer uses just such indexes, but NOT the article_prodcode_idx one.如果我添加例如另一个字段,如优先级或状态,优化器只使用这样的索引,而不是 article_prodcode_idx 索引。 The problem is that the query scans the whole 40 million records, and the result comes after 100 seconds.问题是查询扫描了整个4000万条记录,结果在100秒后出来。 Why the index is not used there?为什么那里不使用索引?

I checked this answer too: MySQL partial indexes on varchar fields and group by optimization but I didn't find any answer to my problem.我也检查了这个答案: varchar 字段上的 MySQL 部分索引和按优化分组,但我没有找到我的问题的任何答案。 What should I do to let the query return results... quickly?我应该怎么做才能让查询返回结果......快速?

Thank you谢谢

After a deep check, I solved the problem.经过深入检查,我解决了问题。 In some ways, I did a mistake in describing the problem.在某些方面,我在描述问题时犯了一个错误。 In fact, in my script, I had something like事实上,在我的脚本中,我有类似的东西

SET @pc='a-4536-x-bef45-green'; 
...
SELECT * FROM article WHERE prodcode=@pc;

while in some other points I had而在其他一些方面我有

SELECT * FROM article WHERE prodcode='a-4536-x-bef45-green';

In the first case, no indexes are used.在第一种情况下,不使用索引。 In the second one, everything works as expected.在第二个中,一切都按预期进行。 This is the explain of the first query:这是第一个查询的解释:

EXPLAIN FORMAT=JSON SELECT * FROM article WHERE prodcode=@pc;
{
  "query_block": {
  "select_id": 1,
  "table": {
    "table_name": "article",
    "access_type": "ALL",
    "rows": 39498773,
    "filtered": 100,
    "attached_condition": "(convert(`shop`.`article`.`prodcode` using utf8mb4) = (@`pc`))"
    }
  }
}

And this is the second one这是第二个

EXPLAIN FORMAT=JSON SELECT * FROM article WHERE prodcode='a-4536-x-bef45-green';

{
"query_block": {
  "select_id": 1,
  "table": {
    "table_name": "article",
    "access_type": "ref",
    "possible_keys": [
      "article_prodcode_idx"
    ],  
    "key": "article_prodcode_idx",
    "used_key_parts": [
      "prodcode"
    ],
    "key_length": "194",
    "ref": [
      "const"
    ],
    "rows": 2,
    "filtered": 100,
    "index_condition": "(`shop`.`article`.`prodcode` = 'a-4536-x-bef45-green')"
    }
  }
}

I tried a lot of times, using eg我尝试了很多次,使用例如

SELECT * FROM article WHERE prodcode in (@pc, 'another code');

but the result is always the same: if a variable is involved, NO indexes are used.但结果始终相同:如果涉及变量,则不使用任何索引。

Knowing, that, I changed my scripts in order to not use SET anymore, and everything started running fine.知道了,我改变了我的脚本,以便不再使用 SET,一切都开始正常运行。

I still would like to know why... but at least the problem is solved.我还是想知道为什么……但至少问题解决了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM