これは「私のために宿題をしてください」のような質問のように感じますが、多くの行を持つテーブルに対してこのクエリをすばやく実行しようとして、ここで立ち往生しています。これは、スキーマを示すSQLFiddleです (多かれ少なかれ)。
必要なすべての列を表示するものを取得しようとして、インデックスをいじりましたが、あまり成功していません。は次のcreate
とおりです。
CREATE TABLE `AuditEvent` (
`auditEventId` bigint(20) NOT NULL AUTO_INCREMENT,
`eventTime` datetime NOT NULL,
`target1Id` int(11) DEFAULT NULL,
`target1Name` varchar(100) DEFAULT NULL,
`target2Id` int(11) DEFAULT NULL,
`target2Name` varchar(100) DEFAULT NULL,
`clientId` int(11) NOT NULL DEFAULT '1',
`type` int(11) not null,
PRIMARY KEY (`auditEventId`),
KEY `Transactions` (`clientId`,`eventTime`,`target1Id`,`type`),
KEY `TransactionsJoin` (`auditEventId`, `clientId`,`eventTime`,`target1Id`,`type`)
)
そして(のバージョン)select
:
select ae.target1Id, ae.type, count(*)
from AuditEvent ae
where ae.clientId=4
and (ae.eventTime between '2011-09-01 03:00:00' and '2012-09-30 23:57:00')
group by ae.target1Id, ae.type;
「一時的な使用」と「ファイルソートの使用」も終了します。を削除して代わりにcount(*)
使用しようとしselect distinct
ましたが、「ファイルソートの使用」は発生しません。join
カウントを取得するために戻る方法があれば、これはおそらく問題ありません。
最初は、監査レコードの作成時に存在していたターゲットの target1Name および target2Name を追跡することが決定されました。それらの名前も必要です (最新のもので十分です)。
現在、クエリ (上記、target1Name 列と target2Name 列が欠落している) は、約 2,400 万件のレコードに対して約 5 秒で実行されます。私たちの目標は数億であり、クエリがそれらの線に沿って引き続き実行されることを望んでいます(1〜2分未満に抑えることを望んでいますが、それをはるかに改善したいと考えています)が、私の懸念は一度ですヒットしない大量のデータにヒットします (追加の行をシミュレートする作業が進行中です)。
追加のフィールドを取得するための最良の戦略がわかりません。列を直接追加するselect
と、クエリの「インデックスの使用」が失われます。join
「使用中のインデックス」を保持するテーブルに戻ることを試みましたが、約 20 秒かかります。
eventTime 列を datetime ではなく int に変更しようとしましたが、インデックスの使用や時間には影響しなかったようです。