0

1 つにはタイムスタンプ値列があり、もう 1 つには日時値列があることを除いて、すべて同じ 2 つのテーブルがあります。インデックスは同じです。値は同じです。

しかし、SELECT station, MAX(timestamp) AS max_timestamp FROM stations GROUP BY station;ステーションがタイムスタンプ付きのステーションである場合に実行すると、非常に高速に実行されます。日時のもので試してみると、1 つのクエリが実行されるのを見たことがありません。どちらの場合も、timestamp列にインデックスが付けられ、型のみが変更されます。

どこから探し始めるべきですか?または、datetime は検索とインデックス作成には適していませんか?

EXPLAINこれが与えるものです:

+----+-------------+-------+-------+---------------+-------+---------+------+------+--------------------------+
| id | select_type | table    | type  | possible_keys | key     | key_len | ref  | rows | Extra                    |
+----+-------------+-------+-------+---------------+-------+---------+------+------+--------------------------+
|  1 | SIMPLE      | stations | range | NULL          | stamp   | 33      | NULL | 1511 | Using index for group-by |
+----+-------------+-------+-------+---------------+-------+---------+------+------+--------------------------+

+----+-------------+--------+-------+---------------+---------+---------+------+---------+-------+
| id | select_type | table    | type  | possible_keys | key     | key_len | ref  | rows    | Extra |
+----+-------------+--------+-------+---------------+---------+---------+------+---------+-------+
|  1 | SIMPLE      |stations2 | index | NULL          | station | 2       | NULL | 3025467 |       |
+----+-------------+--------+-------+---------------+---------+---------+------+---------+-------+

そしてSHOW

+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| stations | CREATE TABLE `stations` (
  `station` varchar(10) COLLATE utf8_bin DEFAULT NULL,
  `available` smallint(6) DEFAULT NULL,
  `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  UNIQUE KEY `stamp` (`station`,`timestamp`),
  KEY `time` (`timestamp`),
  KEY `timestamp` (`timestamp`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

+--------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| stations2 | CREATE TABLE `stations2` (
  `station` smallint(5) unsigned NOT NULL,
  `available` smallint(5) unsigned DEFAULT NULL,
  `timestamp` datetime DEFAULT NULL,
  KEY `station` (`station`),
  KEY `timestamp` (`timestamp`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin |
+--------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
4

1 に答える 1

1

EXPLAINから、選択に使用されているキーがないことがわかります(possible_keysの場合はNULL)。WHERE句がないので、これは理にかなっています。

MySQLはインデックスを利用してMAXを決定でき、インデックスを利用してGROUPBYを最適化できます。ただし、両方を組み合わせて最適化できるようにするには、MAX()関数の列とGROUPBY句の列の両方を複合インデックスに含める必要があります。最初の表には、この複合インデックスが「スタンプ」と呼ばれる一意のキーとしてあります。EXPLAINの結果は、MySQLがそのインデックスを使用していることを示しています。

2番目の表には、この複合インデックスがないため、MySQLはさらに多くの作業を実行する必要があります。結果を手動でグループ化し、各行を手動でスキャンして各ステーションのMAX値を維持する必要があります。2番目のテーブルに同じ複合インデックスを追加すると、2つのテーブル間で同様のパフォーマンスが見られます。

ただし、TIMESTAMPは単一の4バイト整数値として扱われるため、TIMESTAMPはDATETIMEをわずかに上回ります。これは、8バイトの特別なDATETIME値よりも高速に処理されます。データセットが大きいほど、違いが大きくなります。

于 2012-05-25T16:58:07.547 に答える