0

集計を介して要約するために使用しているクエリがあります。

このテーブルは「接続」と呼ばれ、約 8 億 4,300 万行あります。

CREATE TABLE `connections` (
  `app_id` varchar(16) DEFAULT NULL,
  `user_id` bigint(20) DEFAULT NULL,
  `time_started_dt` datetime DEFAULT NULL,
  `device` varchar(255) DEFAULT NULL,
  `os` varchar(255) DEFAULT NULL,
  `firmware` varchar(255) DEFAULT NULL,
  KEY `app_id` (`bid`),
  KEY `time_started_dt` (`time_started_dt`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

以下のようなクエリを実行しようとすると、10 時間以上かかり、最終的に強制終了してしまいます。クエリを最適化する方法について何か提案がありますか?

SELECT
app_id,
MAX(time_started_dt),
MIN(time_started_dt),
COUNT(*)
FROM
connections
GROUP BY
app_id
4

3 に答える 3

1

app_idそのクエリを実行するには、先頭の列として適切なカバリング インデックスが必要です。

CREATE INDEX `connections_IX1` ON `connections` (`app_id`,` time_start_dt`);

注: インデックスの作成には数時間かかる場合があり、実行中はテーブルへの挿入/更新/削除ができなくなります。

EXPLAIN は、クエリの提案された実行計画を表示します。カバリング インデックスが配置されると、プランに「使用インデックス」が表示されます。(「カバリング インデックス」は、基礎となるテーブルにアクセスせずにクエリを満たすために MySQL で使用できるインデックスです。つまり、クエリはインデックスから完全に満たすことができます。)

このテーブルには多数の行があるため、パーティショニングを検討することもできます。

于 2013-07-11T16:38:02.510 に答える
1

に複合インデックスを作成することをお勧めします(app_id, time_started_dt):

ALTER TABLE connections ADD INDEX(app_id, time_started_dt)
于 2013-07-11T16:34:39.597 に答える
0

ランダムに生成されたデータ (約 100 万行) に対してクエリを試しました。PRIMATY KEY を追加すると、クエリのパフォーマンスが 10% 向上します。他の人がすでに示唆しているように、複合インデックスをテーブルに追加する必要があります。インデックス time_started_dt は役に立ちません。

CREATE TABLE `connections` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `app_id` varchar(16) DEFAULT NULL,
  `user_id` bigint(20) DEFAULT NULL,
  `time_started_dt` datetime DEFAULT NULL,
  `device` varchar(255) DEFAULT NULL,
  `os` varchar(255) DEFAULT NULL,
  `firmware` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `composite_idx` (`app_id`,`time_started_dt`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
于 2015-02-20T13:54:05.907 に答える