Postgresql
昂貴子查詢的優化
以下查詢獲取
<> 0
與指定單位關聯的最後一個報告(緯度和經度和秒所在的位置):SELECT reports.* FROM reports INNER JOIN units ON units.id = reports.unit_id WHERE reports.unit_id IN (1111, 1112, 1113) AND ( reports.id = ( SELECT reports.id FROM reports WHERE reports.unit_id = units.id AND reports.time_secs != 0 AND reports.latitude != 0.0 AND reports.longitude != 0.0 ORDER BY time desc LIMIT 1 ) )
此查詢需要幾分鐘才能執行,我想知道是否可以對其進行優化。
這可以通過以下方式變得更加簡單和快捷
DISTINCT ON
:SELECT DISTINCT ON (r.unit_id) r.* FROM reports r JOIN units u ON u.id = r.unit_id WHERE r.unit_id IN (1111, 1112, 1113) AND r.time_secs <> 0 AND r.latitude <> 0.0 AND r.longitude <> 0.0 ORDER BY r.unit_id, r.time DESC;
這些相關答案中的更多解釋:
在每個 GROUP BY 組中選擇第一行?(關於 SO)
次要細節:“不等於”的標準 SQL 運算符是
<>
. 使用它而不是!=
(在 Postgres 中也被接受)。在此查詢中加入表的唯一可能目的**
units
**是驗證是否存在一個或多個相關行。如果reports.unit_id
被外鍵綁定unit.id
(如命名所暗示的那樣),則可以保證引用完整性,並且您可以unit
從查詢中完全刪除表。只需添加:unit_id IS NOT NULL
。SELECT DISTINCT ON (unit_id) * FROM reports WHERE unit_id IN (1111, 1112, 1113) AND time_secs <> 0 AND latitude <> 0.0 AND longitude <> 0.0 AND unit_id IS NOT NULL ORDER BY unit_id, time DESC;