使用最简单的IN语句执行可怕的MySQL索引行为
我发现,如果我为IN语句指定表输出,MySQL(Win7 64,5.6.14)不能正确使用索引。用户表包含900k条记录使用最简单的IN语句执行可怕的MySQL索引行为,mysql,sql,indexing,Mysql,Sql,Indexing,我发现,如果我为IN语句指定表输出,MySQL(Win7 64,5.6.14)不能正确使用索引。用户表包含900k条记录 如果我在(_SOME_TABLE_OUTPUT)语法中使用,我将获得所有900k用户的完整扫描。查询永远运行 如果我在('CONCRETE','VALUES')语法中使用,我会得到正确的索引用法 如何让MySQL最终使用索引 第1例: explain SELECT gu.id FROM USER gu WHERE gu.uuid in (select '11b6a5
explain SELECT gu.id FROM USER gu WHERE gu.uuid in
(select '11b6a540-0dc5-44e0-877d-b3b83f331231' union
select '11b6a540-0dc5-44e0-877d-b3b83f331232');
+----+--------------------+------------+-------+---------------+------+---------+------+--------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+------------+-------+---------------+------+---------+------+--------+--------------------------+
| 1 | PRIMARY | gu | index | NULL | uuid | 257 | NULL | 829930 | Using where; Using index |
| 2 | DEPENDENT SUBQUERY | NULL | NULL | NULL | NULL | NULL | NULL | NULL | No tables used |
| 3 | DEPENDENT UNION | NULL | NULL | NULL | NULL | NULL | NULL | NULL | No tables used |
| NULL | UNION RESULT | <union2,3> | ALL | NULL | NULL | NULL | NULL | NULL | Using temporary |
+----+--------------------+------------+-------+---------------+------+---------+------+--------+--------------------------+
表结构:
CREATE TABLE `USER` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`version` bigint(20) NOT NULL,
`email` varchar(255) DEFAULT NULL,
`uuid` varchar(255) NOT NULL,
`partner_id` bigint(20) NOT NULL,
`password` varchar(255) DEFAULT NULL,
`date_created` datetime DEFAULT NULL,
`last_updated` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `unique-email` (`partner_id`,`email`),
KEY `uuid` (`uuid`),
CONSTRAINT `fk_USER_partner` FOREIGN KEY (`partner_id`) REFERENCES `partner` (`id`) ON DELETE CASCADE,
CONSTRAINT `FKB2D9FEBE725C505E` FOREIGN KEY (`partner_id`) REFERENCES `partner` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3315452 DEFAULT CHARSET=latin1
FORCE INDEX和USE INDEX语句不会更改任何内容
演示SQLFIDLE:虚拟表上的内部联接可能会提供更好的性能。试着用这些方法
SELECT gu.id
FROM USER gu
INNER JOIN (
select '11b6a540-0dc5-44e0-877d-b3b83f331231' uuid
union all
select '11b6a540-0dc5-44e0-877d-b3b83f331232') ids
on gu.uuid = ids.uuid;
事实上,我以前遇到过这样的问题,碰巧有一个表的单列设置为UTF-8,另一个表的单列设置为latin1。不管我做了什么,MySQL坚持不使用索引。这个问题在这篇博文中描述得很好。一旦您成功修复了字符集,我相信任何查询都会起作用。您看到“可能的键”为NULL的地方了吗?这意味着UUID密钥仅用于协助表扫描。虽然不知道如何解决这个问题…相同的结果-fullscan.MySQL在我的测试中使用uuid上的索引,但这可能不相关。什么版本的MySQL?你在SQLFiddle.com上测试过多个版本吗?我使用MySQL(Win764,5.6.14),还没有尝试过SQLFiddle.com。继续尝试。如果从CREATE TABLE语句中剪切
default charset=latin1
,它将使用索引。排序规则中是否存在使查询优化器感到沮丧的不匹配?
SELECT gu.id
FROM USER gu
INNER JOIN (
select '11b6a540-0dc5-44e0-877d-b3b83f331231' uuid
union all
select '11b6a540-0dc5-44e0-877d-b3b83f331232') ids
on gu.uuid = ids.uuid;