Ste*_*han 15 mysql indexing performance limit
如果我将查询限制为1而不是5,我注意到速度急剧下降.
SELECT he. *
FROM homematic_events he
WHERE he.homematic_devices_id =30
ORDER BY id DESC
LIMIT 1
Run Code Online (Sandbox Code Playgroud)
代替
SELECT he. *
FROM homematic_events he
WHERE he.homematic_devices_id =30
ORDER BY id DESC
LIMIT 5
Run Code Online (Sandbox Code Playgroud)
我的表包含大约12,000,000行,具有以下结构:
CREATE TABLE IF NOT EXISTS `homematic_events` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`homematic_devices_id` int(11) DEFAULT NULL,
`address` char(16) COLLATE utf8_unicode_ci NOT NULL,
`interface_id` char(16) COLLATE utf8_unicode_ci NOT NULL,
`key` char(32) COLLATE utf8_unicode_ci NOT NULL,
`value` float(12,2) NOT NULL,
`timestamp` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `timestamp` (`timestamp`),
KEY `address` (`address`),
KEY `key` (`key`),
KEY `homematic_devices_id` (`homematic_devices_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=12637557 ;
Run Code Online (Sandbox Code Playgroud)
这些是对LIMIT 5的速度测量的解释:
mysql> EXPLAIN SELECT he. * FROM homematic_events he WHERE he.homematic_devices_id =30 ORDER BY id DESC LIMIT 5;
+----+-------------+-------+------+----------------------+----------------------+---------+-------+------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+----------------------+----------------------+---------+-------+------+-----------------------------+
| 1 | SIMPLE | he | ref | homematic_devices_id | homematic_devices_id | 5 | const | 4171 | Using where; Using filesort |
+----+-------------+-------+------+----------------------+----------------------+---------+-------+------+-----------------------------+
starting 0.000010
checking query cache for query 0.000030
Opening tables 0.000007
System lock 0.000004
Table lock 0.000015
init 0.000019
optimizing 0.000007
statistics 0.000098
preparing 0.000012
executing 0.000002
Sorting result 0.022965
Sending data 0.000047
end 0.000004
query end 0.000002
freeing items 0.000302
storing result in query cache 0.000009
logging slow query 0.000002
cleaning up 0.000003
Run Code Online (Sandbox Code Playgroud)
这些是对LIMIT 1的速度测量的解释:
mysql> EXPLAIN SELECT he. * FROM homematic_events he WHERE he.homematic_devices_id =30 ORDER BY id DESC LIMIT 1;
+----+-------------+-------+-------+----------------------+---------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+----------------------+---------+---------+------+------+-------------+
| 1 | SIMPLE | he | index | homematic_devices_id | PRIMARY | 4 | NULL | 3029 | Using where |
+----+-------------+-------+-------+----------------------+---------+---------+------+------+-------------+
starting 0.000010
checking query cache for query 0.000034
Opening tables 0.000009
System lock 0.000004
Table lock 0.000015
init 0.000020
optimizing 0.000008
statistics 0.000069
preparing 0.000016
executing 0.000002
Sorting result 0.000005
Sending data 502.290180
end 0.000010
query end 0.000003
freeing items 0.000293
logging slow query 0.000004
logging slow query 0.000002
cleaning up 0.000003
Run Code Online (Sandbox Code Playgroud)
有人可以向我解释这种行为吗?我提到它是由于不同的索引是LIMIT 1的udes的结果.但是为什么mysql对不同的LIMIT值使用不同的键?
使用LIMIT 1,我猜测查询分析器会压缩主键并找到最后一条记录homematic_devices_id =30
- 可能是因为分析器知道"排序"操作会更昂贵.
当你限制5时,我猜测查询分析器决定先找到记录,然后对它们进行排序.如果你想加快操作速度,你可以在homematic_devices_id和ID上创建索引,如下所示:ALTER TABLE homematic_events_test ADD INDEX ( homematic_devices_id, id )
- 首先设置设备ID,你可以容纳"Where"子句,ID列有助于SORT
由于某种原因,MySQL 使用主键而ID
不是索引来访问这些行会更快。homematic_devices_id
即使您专门使用为其构建索引的字段的查询。我还觉得奇怪的是,第二种情况下的 MySQL 只有homematic_devices_id
under possible_keys
,但后来PRIMARY
却选择了。通常,MySQL 会显示PRIMARY
该列中的两个索引和其他可能的索引。
这有可能是一个依赖数据的问题吗?您是否尝试过使用其他 device_id 进行查询?
尝试在这两种情况下使用FORCE INDEX
,看看是否可以解决问题。
归档时间: |
|
查看次数: |
4272 次 |
最近记录: |