1

主キー(bigint)を使用してデータをフェッチするときに非常に遅いように見える非常に単純なテーブルで、いくつかのパフォーマンスの問題と戦っています

1 億 2,400 万のエントリがあるこのテーブルがあります。

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'は 2 つのノード ID を返すだけなので、クエリ全体で返されるのは 2 行のみですが、1 時間ほどかかります。

「force index (PRIMARY)」を使用しても役に立たなかったのですが、なぜMySQLは主キーであるためそのインデックスを取得しないのですか? EXPLAIN は possible_keys 列に何も言及していませんが、select_type は PRIMARY を示しています。

私は何か間違ったことをしていますか?

4

2 に答える 2

1

これは、相関サブクエリと呼ばれるものです。これは参照として、またはStackoverflow に投稿されたこの人気のある質問として見ることができます。使用するより良いクエリは次のとおりです。

SELECT lat,
       lon
FROM nodes n
JOIN ways_elements w ON n.id = w.node_id
WHERE way_id = '4962890'
于 2013-04-15T10:23:48.187 に答える