【发布时间】:2016-09-16 08:19:06
【问题描述】:
也许索引不相关,但我遇到了一个奇怪的问题。
这是我的选择查询:
SELECT DISTINCT completeAddress FROM DB_M3_Medium.AvailableAddressesV3 where postNr = 1050 ORDER BY completeAddress ASC;
我的索引:
create index postNrAndAddress_idx on DB_M3_Medium.AvailableAddressesV3 (completeAddress);
create index postNr_idx on DB_M3_Medium.AvailableAddressesV3 (completeAddress);
create index completeAddress_idx on DB_M3_Medium.AvailableAddressesV3 (completeAddress);
除此之外,我还有一个自动增量 ID (idIndex) 的 PK。
在任何手动创建的索引出现之前,选择查询的执行时间为 2.4 秒。
然后我创建了索引(一个一个):
- 第一个索引 - 选择语句执行时间 - 2.1s
- 第二个索引 - 选择 语句执行时间 - 2.8s
- 第三个索引 - 选择语句 执行时间 - 12.7 秒
刚刚发生了什么?
编辑:
谢谢你们的cmets。我的解释语句结果:
+----+-------------+----------------------+-------+-----------------------------------------------------+---------------------+---------+-----+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------------------+-------+-----------------------------------------------------+---------------------+---------+-----+---------+-------------+
| 1 | SIMPLE | AvailableAddressesV3 | index | postNrAndAddress_idx,postNr_idx,completeAddress_idx | completeAddress_idx | 363 | | 3526406 | Using where |
+----+-------------+----------------------+-------+-----------------------------------------------------+---------------------+---------+-----+---------+-------------+
表结构:
+------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+--------------+------+-----+---------+----------------+
| vej_Navn | varchar(70) | YES | | | |
| husNr | varchar(20) | YES | | | |
| husbogstav | varchar(50) | YES | | | |
| etage | varchar(30) | YES | | | |
| side_DoerNr | varchar(20) | YES | | | |
| stedNavn | varchar(50) | YES | | | |
| postNr | varchar(15) | YES | MUL | | |
| postDistrikt | varchar(50) | YES | | | |
| lev_Adresse_UUID | varchar(50) | YES | | | |
| fiberstatus | varchar(15) | YES | | | |
| kommune_nr | varchar(35) | YES | | | |
| vej_Kode | varchar(35) | YES | | | |
| completeAddress | varchar(120) | YES | MUL | | |
| randomSalt | varchar(5) | YES | | | |
| id | int(11) | NO | PRI | | auto_increment |
+------------------+--------------+------+-----+---------+----------------+
创建表查询:
CREATE TABLE `AvailableAddressesV3` (
`vej_Navn` varchar(70) COLLATE utf8_unicode_ci DEFAULT NULL,
`husNr` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL,
`husbogstav` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
`etage` varchar(30) COLLATE utf8_unicode_ci DEFAULT NULL,
`side_DoerNr` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL,
`stedNavn` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
`postNr` varchar(15) CHARACTER SET utf8 DEFAULT NULL,
`postDistrikt` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
`lev_Adresse_UUID` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
`fiberstatus` varchar(15) COLLATE utf8_unicode_ci DEFAULT NULL,
`kommune_nr` varchar(35) COLLATE utf8_unicode_ci DEFAULT NULL,
`vej_Kode` varchar(35) COLLATE utf8_unicode_ci DEFAULT NULL,
`completeAddress` varchar(120) COLLATE utf8_unicode_ci DEFAULT NULL,
`randomSalt` varchar(5) COLLATE utf8_unicode_ci DEFAULT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
UNIQUE KEY `idIndex` (`id`),
KEY `postNrAndAddress_idx` (`postNr`,`completeAddress`),
KEY `postNr_idx` (`postNr`),
KEY `completeAddress_idx` (`completeAddress`)
) ENGINE=InnoDB AUTO_INCREMENT=3552718 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
【问题讨论】:
-
你的第一站为什么是我的查询做这个问题:dev.mysql.com/doc/refman/5.7/en/explain.html
-
我猜这是一个复制和粘贴错误,但你添加了三倍相同的索引(总是在
completeAddress)。除了按照 CBroe 的建议显示 EXPLAIN 语句结果之外,还要发布您的架构。 -
谢谢,请查看编辑。
-
请注意,每个索引可能会加快 SELECT 查询,但会减慢 UPDATE/INSERT/DELETE,因为必须更新此索引。很容易“猜测”添加所有可能的索引并希望一切运行得更快。
-
@Drew 可以。但是在大表上放10个不必要的索引,然后看看速度是如何变慢的。不是几秒钟,但查询可能需要 0.3 秒而不是 0.001 秒。对于密集的工作,这是有价值的。而对于百万行表,时间可以不是 0.3 秒,而是 3 秒。
标签: mysql