これは「私の宿題を私のために」するような感じですが、ここでは多くの行がある表に対してこの問合せをすばやく実行しようとしています。 Here's a SQLFiddle(多かれ少なかれ)スキーマを示しています。何億もの行を持つ表の問合せを最適化する
私は索引と一緒に試してみましたが、必要なすべての列が表示されますが、それほど成功していないものを取得しようとしました。
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
:ここcreate
だ
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;
私も 'を使用し、一時的な' と '使用filesortレコード' で終わります。 count(*)
を削除し、代わりにselect distinct
を使用しましたが、これは 'Using filesort'を引き起こしませんでした。カウントを得るために戻ってjoin
への道があればこれはおそらく大丈夫でしょう。
元々、監査レコードの作成時に存在していたターゲットのtarget1Nameとtarget2Nameを追跡することが決定されました。私はそれらの名前も必要です(最新のものがあります)。
現在、上記のクエリ(上記のtarget1Nameおよびtarget2Name列がない)は、約2400万レコードで約5秒で実行されます。私たちの目標は数億に過ぎず、これらの行に沿ってクエリを実行し続けたいと思います(1-2分以内にしたいと思っていますが、もっとうまくやっていきたいですが)私たちはそれほど大量のデータを打たなかった(追加の行をシミュレートする作業が進行中)。
私は、追加のフィールドを取得するための最良の戦略についてはよく分かりません。 select
に列を直接追加すると、クエリで「インデックスの使用」が失われます。私はjoin
をテーブルに戻してみました。これは 'Using index'を保持していますが、約20秒かかっています。
eventTime列をdatetimeではなくintに変更しようとしましたが、インデックスの使用や時間に影響していないようです。
あなたの現在のクエリのタイミングと何が下に理解しては何ですか"早く"? – feeela
申し訳ありません、それらの詳細を追加しました –
clientIdとeventTimeにインデックスがありますか?また、eventTime索引を使用しており、フル・テーブル・スキャンを行っていないものがあるかどうかを確認してください。 –