私は非常に単純なクエリを持っています(greatest-n-per-group
の状況でサブクエリとして使用されています)。 state_id
がプライマリキーです。他はすべて一意ではありません。グループ単位の最大n個のサブクエリで範囲フィルタを使用すると、パフォーマンスが非常に悪くなります。
SELECT max(states.state_id) AS max_state_id
FROM states
WHERE states.created >= '2017-06-10 21:53:38.977455'
AND states.created < '2017-06-26 07:00:00'
GROUP BY states.entity_id;
問題があり、このクエリは恐ろしく遅いです、と私は複数列のインデックスの任意の順序はそれにそれが書かれている方法を解決することができるとは思いません。我々はここで何をしようとして、2つのタイムスタンプ間に各entity_id
の最新state_id
を取得している:それははっきりしていない場合、それは常にusing where; using index; using temporary; using filesort
で終わります。
代わりにmax(states.created)
(max(states.state_id)
ではなく)を使用してください。これはおそらくもっと良い方法ですが、外部クエリに参加するためのstate_id
はありません。ここで
は完全なコンテキストを与えるために、外側の部分を含む完全なクエリです:ルースインデックススキャンを行うには、インデックスを許可するよう
SELECT states.state_id AS states_state_id, states.domain AS states_domain, states.entity_id AS states_entity_id, states.state AS states_state, states.attributes AS states_attributes, states.event_id AS states_event_id, states.last_changed AS states_last_changed, states.last_updated AS states_last_updated, states.created AS states_created
FROM states INNER JOIN (
SELECT max(states.state_id) AS max_state_id
FROM states
WHERE states.created >= '2017-06-10 21:53:38.977455' AND states.created < '2017-06-26 07:00:00' GROUP BY states.entity_id
) AS anon_1 ON states.state_id = anon_1.max_state_id;
は確かに、このような方法で、この問合せをリライトする方法が必要...このクエリの
外部クエリに他のすべての列が含まれているのはなぜですか?また、あなたの 'MAX'クエリは、より高い' state_id'が後で作成されたということを意味しない場合、間違っている可能性があります。 –
@FelixPamittan:外部クエリは、単にアプリケーションが必要とする値を返すだけです。簡潔にするため、すべてを 'select * 'に置き換えることができます。作成されたvs state_idに関しては、私は同意し、私はそれを私の質問で述べました。しかし、私たちがstate_idの最大値を取得しない場合、私は外側のクエリがそれにどのように結合するのかはわかりません – OverloadUT
すべての'entity_id 'に対して同じ期間をクエリしていますか? – Horaciux