mysql不使用主bigint索引

时间:2013-04-15 09:18:03

标签: mysql indexing database-performance

在一个非常简单的表上遇到一些性能问题,在使用主键(bigint)获取数据时似乎非常慢

我有这个表有1.24亿个条目:

CREATE TABLE `nodes` (
  `id` bigint(20) NOT NULL,
  `lat` float(13,7) NOT NULL,
  `lon` float(13,7) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `lat_index` (`lat`),
  KEY `lon_index` (`lon`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

和一个简单的查询,它使用IN子句从另一个表获取一些id来从节点表中获取数据,但是从这个表中获取几行只需要1个小时。 EXPLAIN显示我没有使用PRIMARY键作为索引,它只是扫描整个表。为什么? id和另一个表中的id列都来自bigint(20)类型。

mysql> EXPLAIN SELECT lat, lon FROM nodes WHERE id IN (SELECT node_id FROM ways_elements WHERE way_id = '4962890');
+----+--------------------+-------------------+------+---------------+--------+---------+-------+-----------+-------------+
| id | select_type        | table             | type | possible_keys | key    | key_len | ref   | rows      | Extra       |
+----+--------------------+-------------------+------+---------------+--------+---------+-------+-----------+-------------+
|  1 | PRIMARY            | nodes             | ALL  | NULL          | NULL   | NULL    | NULL  | 124035228 | Using where | 
|  2 | DEPENDENT SUBQUERY | ways_elements     | ref  | way_id        | way_id | 8       | const |         2 | Using where | 
+----+--------------------+-------------------+------+---------------+--------+---------+-------+-----------+-------------+

查询SELECT node_id FROM ways_elements WHERE way_id = '4962890'只返回两个节点ID,因此整个查询应该只返回两行,但需要花费大约1小时的时间。

使用“强制索引(PRIMARY)”没有帮助,即使它会有所帮助,为什么MySQL不接受该索引,因为它是一个主键? EXPLAIN甚至没有提到possible_keys列中的任何内容,但select_type显示为PRIMARY。

我做错了吗?

2 个答案:

答案 0 :(得分:1)

这是如何表现的?

SELECT lat, lon FROM nodes t1 join ways_elements t2 on (t1.id=t2.node_id) WHERE t2.way_id = '4962890'

我怀疑你的查询正在检查节点中的每一行对照" IN"中的每一项。子句。

答案 1 :(得分:1)

这就是所谓的相关子查询。您可以在Stackoverflow上看到this作为参考或this热门问题。一个更好的查询使用是:

SELECT lat,
       lon
FROM nodes n
JOIN ways_elements w ON n.id = w.node_id
WHERE way_id = '4962890'