我有一個相當簡單的查詢(用作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;
的問題是,這種查詢是驚人,慢,我不相信多列索引的任何命令可以解決這個問題它的編寫方式。我們試圖在這裏做的是得到每個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;
當然必須有辦法以這種方式來重寫此查詢允許索引做一個鬆散索引掃描...
爲什麼外層查詢包含所有其他列?另外,如果更高的'state_id'並不意味着它稍後被創建,那麼'MAX'查詢可能是錯誤的。 –
@FelixPamittan:好的,外層查詢只是返回應用程序需要的值。爲了簡潔起見,我們可以用'select *'替換所有的。至於創建的vs state_id,我確實同意,並在我的問題中提到過。但是,如果我們沒有得到state_id的最大值,我不確定外部查詢將如何加入到它 – OverloadUT
您是否在查詢所有'entity_id'的同一時間段? – Horaciux