问题描述
有MariaDB 10.4.14,max_join_size = 300M,以及带有约150,000条记录的硬币式InnoDB表。
SELECT * FROM coin z -- USE INDEX(PRIMARY)
WHERE z.id IN (5510,5511,5512 /* more item IDs up to 250 */)
AND z.currency_id IN (8,227)
AND z.distribution_id IN (1,2);
Error Code: 1104
The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET sql_BIG_SELECTS=1 or SET MAX_JOIN_SIZE=# if the SELECT is okay
但是带有索引提示的相同查询效果很好。命中[“ PRIMARY”,“ currency_id_idx”,“ distribution_id”]甚至是issue_date_idx都无关紧要 即使根本没有索引USE INDEX(),它也可以工作。
顺便说一句,此查询在MariaDB 10.3.24上运行良好,而在10.5.5上不工作
OPTIMIZE TABLE coin; -- didn't help
Table DDL and query EXPLAIN
CREATE TABLE `coin` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,`name` varchar(90) NOT NULL DEFAULT '',`country_id` smallint(5) unsigned NOT NULL DEFAULT 0,`currency_id` smallint(5) unsigned NOT NULL DEFAULT 0,`distribution_id` tinyint(3) unsigned NOT NULL,`issue_date` date NOT NULL DEFAULT '0000-00-00',-- and other,total 29 fields
PRIMARY KEY (`id`),KEY `issue_date_idx` (`issue_date`),KEY `currency_id_idx` (`currency_id`),KEY `distribution_id` (`distribution_id`),total 21 indices for other fields which don't use currency_id or distribution_id
CONSTRAINT `coin_ibfk_4` FOREIGN KEY (`currency_id`) REFERENCES `currency` (`id`),CONSTRAINT `coin_ibfk_11` FOREIGN KEY (`distribution_id`) REFERENCES `distribution` (`id`),total 13 CONSTRAINTs
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
EXPLAIN FORMAT=JSON -- for SELECT above without index hint
{
"query_block": {
"select_id": 1,"table": {
"table_name": "z","access_type": "range","possible_keys": ["PRIMARY","currency_id_idx","distribution_id"],"key": "PRIMARY","key_length": "3","used_key_parts": ["id"],"rows": 50,"filtered": 100,"attached_condition": "z.`id` in (5510,5512,/* ... total 100 */) and z.currency_id in (8,227) and z.distribution_id in (1,2)"
}
}
}
上面的SELECT在没有可能具有最大MAX_JOIN_SIZE值且没有最大值-1:的索引提示的情况下工作
SET MAX_JOIN_SIZE=18446744073709551615 -- this works
SET MAX_JOIN_SIZE=18446744073709551614 -- this doesn't work
解决方法
可以通过恢复先前的默认值来修复MAX_JOIN_SIZE错误
a->c
d->d
e->g
h->h
i->k
l->l
m->m
n->n
o->q
r->r
s->s
t->t
u->w
x->x
y->None