2014-09-23 68 views
0

爲了優化數據庫訪問,我必須在單個視圖中彙總每個表的最後'閱讀',但我注意到執行許多單個查詢的成本遠低於使用視圖的成本,我想知道我的觀點是否有問題,或者可以優化。在postgresql中查看優化

這裏是一些表:

CREATE TABLE hives(
    id character(20) NOT NULL, 
    master character(20) DEFAULT NULL::bpchar, 
    owner integer, 
    [...] 
    CONSTRAINT hives_pkey PRIMARY KEY (id), 
    CONSTRAINT hives_master_extk FOREIGN KEY (master) 
     REFERENCES hives (id) MATCH SIMPLE 
     ON UPDATE CASCADE ON DELETE SET NULL, 
    CONSTRAINT hives_owner_extk FOREIGN KEY (owner) 
     REFERENCES users (id) MATCH SIMPLE 
     ON UPDATE CASCADE ON DELETE CASCADE 
) 

CREATE TABLE dt_rain(
    hive character(20) NOT NULL, 
    hiveconnection integer, 
    instant timestamp with time zone NOT NULL, 
    rain integer, 
    CONSTRAINT dt_rain_pkey PRIMARY KEY (hive, instant), 
    CONSTRAINT dt_rain_hive_connections_extk FOREIGN KEY (hiveconnection) 
     REFERENCES hives_connections (id) MATCH SIMPLE 
     ON UPDATE CASCADE ON DELETE SET NULL, 
    CONSTRAINT dt_rain_hive_extk FOREIGN KEY (hive) 
     REFERENCES hives (id) MATCH SIMPLE 
     ON UPDATE CASCADE ON DELETE CASCADE 
) 

CREATE TABLE dt_temperature 
(
    hive character(20) NOT NULL, 
    hiveconnection integer, 
    instant timestamp with time zone NOT NULL, 
    internal integer, 
    external integer, 
    CONSTRAINT dt_temperature_pkey PRIMARY KEY (hive, instant), 
    CONSTRAINT dt_temperature_hive_connections_extk FOREIGN KEY (hiveconnection) 
     REFERENCES hives_connections (id) MATCH SIMPLE 
     ON UPDATE CASCADE ON DELETE SET NULL, 
    CONSTRAINT dt_temperature_hive_extk FOREIGN KEY (hive) 
     REFERENCES hives (id) MATCH SIMPLE 
     ON UPDATE CASCADE ON DELETE CASCADE 
) 

數據表持有所有讀數的歷史,是非常大的,共享相同的格式:蜂房(關鍵蕁麻疹表),即時data

我很感興趣,所以這裏只獲得最後一個值是認爲:

從這個觀點
CREATE OR REPLACE VIEW dt_last AS 
SELECT id AS 
    hive, 
    b.instant AS inout_instant, "input", "output", timeout, 
    c.instant AS temperature_instant, "internal", "external", 
    d.instant AS weight_instant, weight, 
    e.instant AS rain_instant, rain, 
    f.instant AS voltage_instant, operational, panel, cell, 
    g.instant AS gps_instant, latitude, longitude, altitude 
FROM hives 
LEFT OUTER JOIN (
    SELECT hive, instant, "input", "output", timeout FROM dt_inout_summary x 
     WHERE x.instant = (
      SELECT MAX(x1.instant) FROM dt_inout_summary x1 WHERE x1.hive = x.hive 
     ) 
    ) b ON (id = b.hive) 
LEFT OUTER JOIN (
    SELECT hive, instant, "internal", "external" FROM dt_temperature x 
     WHERE x.instant = (
      SELECT MAX(x1.instant) FROM dt_temperature x1 WHERE x1.hive = x.hive 
     ) 
    ) c ON (id = c.hive) 
LEFT OUTER JOIN (
    SELECT hive, instant, weight FROM dt_weight x 
     WHERE x.instant = (
      SELECT MAX(x1.instant) FROM dt_weight x1 WHERE x1.hive = x.hive 
     ) 
    ) d ON (id = d.hive) 
LEFT OUTER JOIN (
    SELECT hive, instant, rain FROM dt_rain x 
     WHERE x.instant = (
      SELECT MAX(x1.instant) FROM dt_inout_summary x1 WHERE x1.hive = x.hive 
     ) 
    ) e ON (id = e.hive) 
LEFT OUTER JOIN (
    SELECT hive, instant, operational, panel, cell FROM dt_voltage x 
     WHERE x.instant = (
      SELECT MAX(x1.instant) FROM dt_inout_summary x1 WHERE x1.hive = x.hive 
     ) 
    ) f ON (id = f.hive) 
LEFT OUTER JOIN (
    SELECT hive, instant, latitude, longitude, altitude FROM dt_gps x 
     WHERE x.instant = (
      SELECT MAX(x1.instant) FROM dt_gps x1 WHERE x1.hive = x.hive 
     ) 
    ) g ON (id = g.hive) 

選擇收費記錄至極約1秒比執行SELECT * FROM WHERE蜂巢貴得多=''ORDER BY即時DESC限制1;每個蜂巢6次。 我不解

這裏是查詢分析器,然後解釋圖形視角分析輸出 planner

Merge Left Join (cost=127051.81..264142.76 rows=37741 width=153) (actual time=8862.466..8862.564 rows=13 loops=1) 
    Merge Cond: (hives.id = x_1.hive) 
    -> Nested Loop Left Join (cost=0.29..136523.11 rows=801 width=137) (actual time=4198.324..4198.395 rows=13 loops=1) 
     Join Filter: (hives.id = x_5.hive) 
     Rows Removed by Join Filter: 36 
     -> Nested Loop Left Join (cost=0.29..136505.79 rows=801 width=85) (actual time=4198.300..4198.363 rows=13 loops=1) 
       Join Filter: (hives.id = x_4.hive) 
       -> Nested Loop Left Join (cost=0.29..135968.88 rows=801 width=65) (actual time=4198.254..4198.315 rows=13 loops=1) 
        Join Filter: (hives.id = x_3.hive) 
        Rows Removed by Join Filter: 12 
        -> Nested Loop Left Join (cost=0.29..135407.01 rows=801 width=53) (actual time=4198.171..4198.227 rows=13 loops=1) 
          Join Filter: (hives.id = x.hive) 
          Rows Removed by Join Filter: 108 
          -> Nested Loop Left Join (cost=0.29..345.31 rows=17 width=33) (actual time=0.011..0.049 rows=13 loops=1) 
           -> Index Only Scan using hives_pkey on hives (cost=0.14..12.39 rows=17 width=21) (actual time=0.005..0.011 rows=13 loops=1) 
             Heap Fetches: 13 
           -> Index Scan using dt_weight_pkey on dt_weight x_2 (cost=0.15..19.57 rows=1 width=96) (actual time=0.002..0.002 rows=0 loops=13) 
             Index Cond: (hives.id = hive) 
             Filter: (instant = (SubPlan 6)) 
             SubPlan 6 
             -> Result (cost=5.50..5.51 rows=1 width=0) (actual time=0.009..0.009 rows=1 loops=1) 
               InitPlan 5 (returns $5) 
               -> Limit (cost=0.15..5.50 rows=1 width=8) (actual time=0.007..0.007 rows=1 loops=1) 
                 -> Index Only Scan Backward using dt_weight_pkey on dt_weight x1_2 (cost=0.15..16.21 rows=3 width=8) (actual time=0.003..0.003 rows=1 loops=1) 
                  Index Cond: ((hive = x_2.hive) AND (instant IS NOT NULL)) 
                  Heap Fetches: 1 
          -> Materialize (cost=0.00..134859.45 rows=801 width=41) (actual time=198.865..322.935 rows=9 loops=13) 
           -> Seq Scan on dt_inout_summary x (cost=0.00..134855.44 rows=801 width=41) (actual time=2585.238..4198.146 rows=9 loops=1) 
             Filter: (instant = (SubPlan 2)) 
             Rows Removed by Filter: 160099 
             SubPlan 2 
             -> Result (cost=0.81..0.82 rows=1 width=0) (actual time=0.026..0.026 rows=1 loops=160108) 
               InitPlan 1 (returns $1) 
               -> Limit (cost=0.42..0.81 rows=1 width=8) (actual time=0.025..0.025 rows=1 loops=160108) 
                 -> Index Only Scan Backward using test on dt_inout_summary x1 (cost=0.42..6929.02 rows=17790 width=8) (actual time=0.025..0.025 rows=1 loops=160108) 
                  Index Cond: ((hive = x.hive) AND (instant IS NOT NULL)) 
                  Heap Fetches: 160108 
        -> Materialize (cost=0.00..525.83 rows=3 width=96) (actual time=0.006..0.006 rows=1 loops=13) 
          -> Seq Scan on dt_rain x_3 (cost=0.00..525.82 rows=3 width=96) (actual time=0.076..0.076 rows=1 loops=1) 
           Filter: (instant = (SubPlan 8)) 
           Rows Removed by Filter: 2 
           SubPlan 8 
            -> Result (cost=0.81..0.82 rows=1 width=0) (actual time=0.023..0.023 rows=1 loops=3) 
             InitPlan 7 (returns $7) 
              -> Limit (cost=0.42..0.81 rows=1 width=8) (actual time=0.023..0.023 rows=1 loops=3) 
               -> Index Only Scan Backward using test on dt_inout_summary x1_3 (cost=0.42..6929.02 rows=17790 width=8) (actual time=0.022..0.022 rows=1 loops=3) 
                 Index Cond: ((hive = x_3.hive) AND (instant IS NOT NULL)) 
                 Heap Fetches: 3 
       -> Materialize (cost=0.00..500.88 rows=3 width=104) (actual time=0.004..0.004 rows=0 loops=13) 
        -> Seq Scan on dt_voltage x_4 (cost=0.00..500.86 rows=3 width=104) (actual time=0.045..0.045 rows=0 loops=1) 
          Filter: (instant = (SubPlan 10)) 
          Rows Removed by Filter: 2 
          SubPlan 10 
          -> Result (cost=0.81..0.82 rows=1 width=0) (actual time=0.021..0.021 rows=1 loops=2) 
            InitPlan 9 (returns $9) 
            -> Limit (cost=0.42..0.81 rows=1 width=8) (actual time=0.020..0.020 rows=1 loops=2) 
              -> Index Only Scan Backward using test on dt_inout_summary x1_4 (cost=0.42..6929.02 rows=17790 width=8) (actual time=0.019..0.019 rows=1 loops=2) 
               Index Cond: ((hive = x_4.hive) AND (instant IS NOT NULL)) 
               Heap Fetches: 2 
     -> Materialize (cost=0.00..5.30 rows=1 width=136) (actual time=0.001..0.002 rows=3 loops=13) 
       -> Seq Scan on dt_gps x_5 (cost=0.00..5.30 rows=1 width=136) (actual time=0.009..0.018 rows=3 loops=1) 
        Filter: (instant = (SubPlan 11)) 
        Rows Removed by Filter: 3 
        SubPlan 11 
         -> Aggregate (cost=1.05..1.06 rows=1 width=8) (actual time=0.002..0.002 rows=1 loops=6) 
          -> Seq Scan on dt_gps x1_5 (cost=0.00..1.05 rows=1 width=8) (actual time=0.001..0.001 rows=3 loops=6) 
            Filter: (hive = x_5.hive) 
            Rows Removed by Filter: 3 
    -> Sort (cost=127051.53..127053.53 rows=801 width=37) (actual time=4664.139..4664.139 rows=9 loops=1) 
     Sort Key: x_1.hive 
     Sort Method: quicksort Memory: 25kB 
     -> Seq Scan on dt_temperature x_1 (cost=0.00..127012.90 rows=801 width=37) (actual time=2859.376..4664.118 rows=9 loops=1) 
       Filter: (instant = (SubPlan 4)) 
       Rows Removed by Filter: 160098 
       SubPlan 4 
       -> Result (cost=0.76..0.77 rows=1 width=0) (actual time=0.029..0.029 rows=1 loops=160107) 
         InitPlan 3 (returns $3) 
         -> Limit (cost=0.42..0.76 rows=1 width=8) (actual time=0.028..0.028 rows=1 loops=160107) 
           -> Index Only Scan Backward using dt_temperature_pkey on dt_temperature x1_1 (cost=0.42..6834.25 rows=20013 width=8) (actual time=0.028..0.028 rows=1 loops=160107) 
            Index Cond: ((hive = x_1.hive) AND (instant IS NOT NULL)) 
            Heap Fetches: 160107 
Total runtime: 8862.684 ms 

有沒有辦法來優化以任何方式對此有何看法?

===編輯與MAX建議由喬普與未更換EXISTS和索引(蜂巢,即時DESC)

CREATE OR REPLACE VIEW dt_last4 AS 
SELECT hives.id AS hive, 
    b.instant AS inout_instant, 
    b.input, 
    b.output, 
    b.timeout, 
    c.instant AS temperature_instant, 
    c.internal, 
    c.external, 
    d.instant AS weight_instant, 
    d.weight, 
    e.instant AS rain_instant, 
    e.rain, 
    f.instant AS voltage_instant, 
    f.operational, 
    f.panel, 
    f.cell, 
    g.instant AS gps_instant, 
    g.latitude, 
    g.longitude, 
    g.altitude 
    FROM hives 
    LEFT JOIN dt_inout_summary b ON b.hive = hives.id AND NOT (EXISTS (SELECT 1 
      FROM dt_inout_summary nx 
      WHERE nx.hive = b.hive AND nx.instant > b.instant)) 
    LEFT JOIN dt_temperature c ON c.hive = hives.id AND NOT (EXISTS (SELECT 1 
      FROM dt_temperature nx 
      WHERE nx.hive = c.hive AND nx.instant > c.instant)) 
    LEFT JOIN dt_weight d ON d.hive = hives.id AND NOT (EXISTS (SELECT 1 
      FROM dt_weight nx 
      WHERE nx.hive = d.hive AND nx.instant > d.instant)) 
    LEFT JOIN dt_rain e ON e.hive = hives.id AND NOT (EXISTS (SELECT 1 
      FROM dt_rain nx 
      WHERE nx.hive = e.hive AND nx.instant > e.instant)) 
    LEFT JOIN dt_voltage f ON f.hive = hives.id AND NOT (EXISTS (SELECT 1 
      FROM dt_voltage nx 
      WHERE nx.hive = f.hive AND nx.instant > f.instant)) 
    LEFT JOIN dt_gps g ON g.hive = hives.id AND NOT (EXISTS (SELECT 1 
      FROM dt_gps nx 
      WHERE nx.hive = g.hive AND nx.instant > g.instant)); 

EXPLAIN分析一下: enter image description here

Hash Left Join (cost=18746.60..17942207.21 rows=670182787 width=153) (actual time=771.791..3488.536 rows=13 loops=1) 
    Hash Cond: (hives.id = e.hive) 
    -> Hash Left Join (cost=18744.45..14640569.26 rows=670182787 width=141) (actual time=771.776..3488.513 rows=13 loops=1) 
     Hash Cond: (hives.id = f.hive) 
     -> Hash Left Join (cost=18742.35..11733156.54 rows=670182787 width=121) (actual time=771.759..3488.486 rows=13 loops=1) 
       Hash Cond: (hives.id = g.hive) 
       -> Hash Right Join (cost=18740.04..7643068.10 rows=670182787 width=69) (actual time=771.730..3488.447 rows=13 loops=1) 
        Hash Cond: (b.hive = hives.id) 
        -> Nested Loop Anti Join (cost=0.84..81545.46 rows=106739 width=41) (actual time=585.381..3301.662 rows=9 loops=1) 
          -> Index Scan using dt_inout_summary_hive_idx on dt_inout_summary b (cost=0.42..11549.35 rows=160108 width=41) (actual time=0.012..33.690 rows=160108 loops=1) 
          -> Index Only Scan using dt_inout_summary_hive_instant_idx on dt_inout_summary nx (cost=0.42..119.09 rows=5930 width=29) (actual time=0.020..0.020 rows=1 loops=160108) 
           Index Cond: ((hive = b.hive) AND (instant > b.instant)) 
           Heap Fetches: 160099 
        -> Hash (cost=16361.97..16361.97 rows=106738 width=49) (actual time=186.324..186.324 rows=13 loops=1) 
          Buckets: 2048 Batches: 16 Memory Usage: 1kB 
          -> Hash Right Join (cost=6197.92..16361.97 rows=106738 width=49) (actual time=109.280..186.247 rows=13 loops=1) 
           Hash Cond: (c.hive = hives.id) 
           -> Hash Anti Join (cost=6194.41..14890.81 rows=106738 width=37) (actual time=109.245..186.196 rows=9 loops=1) 
             Hash Cond: (c.hive = nx_1.hive) 
             Join Filter: (nx_1.instant > c.instant) 
             Rows Removed by Join Filter: 195309 
             -> Seq Scan on dt_temperature c (cost=0.00..3098.07 rows=160107 width=37) (actual time=0.004..18.177 rows=160107 loops=1) 
             -> Hash (cost=3098.07..3098.07 rows=160107 width=29) (actual time=48.792..48.792 rows=160107 loops=1) 
              Buckets: 2048 Batches: 32 (originally 16) Memory Usage: 4175kB 
              -> Seq Scan on dt_temperature nx_1 (cost=0.00..3098.07 rows=160107 width=29) (actual time=0.002..17.848 rows=160107 loops=1) 
           -> Hash (cost=3.30..3.30 rows=17 width=33) (actual time=0.029..0.029 rows=13 loops=1) 
             Buckets: 1024 Batches: 1 Memory Usage: 1kB 
             -> Hash Left Join (cost=2.06..3.30 rows=17 width=33) (actual time=0.023..0.028 rows=13 loops=1) 
              Hash Cond: (hives.id = d.hive) 
              -> Seq Scan on hives (cost=0.00..1.17 rows=17 width=21) (actual time=0.004..0.006 rows=13 loops=1) 
              -> Hash (cost=2.04..2.04 rows=1 width=33) (actual time=0.013..0.013 rows=1 loops=1) 
                Buckets: 1024 Batches: 1 Memory Usage: 1kB 
                -> Nested Loop Anti Join (cost=0.00..2.04 rows=1 width=33) (actual time=0.012..0.012 rows=1 loops=1) 
                 Join Filter: ((nx_2.instant > d.instant) AND (nx_2.hive = d.hive)) 
                 Rows Removed by Join Filter: 1 
                 -> Seq Scan on dt_weight d (cost=0.00..1.01 rows=1 width=33) (actual time=0.004..0.004 rows=1 loops=1) 
                 -> Materialize (cost=0.00..1.01 rows=1 width=29) (actual time=0.003..0.003 rows=1 loops=1) 
                   -> Seq Scan on dt_weight nx_2 (cost=0.00..1.01 rows=1 width=29) (actual time=0.002..0.002 rows=1 loops=1) 
       -> Hash (cost=2.26..2.26 rows=4 width=136) (actual time=0.019..0.019 rows=3 loops=1) 
        Buckets: 1024 Batches: 1 Memory Usage: 1kB 
        -> Hash Anti Join (cost=1.14..2.26 rows=4 width=136) (actual time=0.015..0.018 rows=3 loops=1) 
          Hash Cond: (g.hive = nx_5.hive) 
          Join Filter: (nx_5.instant > g.instant) 
          Rows Removed by Join Filter: 9 
          -> Seq Scan on dt_gps g (cost=0.00..1.06 rows=6 width=136) (actual time=0.004..0.004 rows=6 loops=1) 
          -> Hash (cost=1.06..1.06 rows=6 width=92) (actual time=0.004..0.004 rows=6 loops=1) 
           Buckets: 1024 Batches: 1 Memory Usage: 1kB 
           -> Seq Scan on dt_gps nx_5 (cost=0.00..1.06 rows=6 width=92) (actual time=0.001..0.002 rows=6 loops=1) 
     -> Hash (cost=2.08..2.08 rows=1 width=104) (actual time=0.014..0.014 rows=1 loops=1) 
       Buckets: 1024 Batches: 1 Memory Usage: 1kB 
       -> Hash Anti Join (cost=1.04..2.08 rows=1 width=104) (actual time=0.012..0.012 rows=1 loops=1) 
        Hash Cond: (f.hive = nx_4.hive) 
        Join Filter: (nx_4.instant > f.instant) 
        Rows Removed by Join Filter: 2 
        -> Seq Scan on dt_voltage f (cost=0.00..1.02 rows=2 width=104) (actual time=0.001..0.001 rows=2 loops=1) 
        -> Hash (cost=1.02..1.02 rows=2 width=92) (actual time=0.002..0.002 rows=2 loops=1) 
          Buckets: 1024 Batches: 1 Memory Usage: 1kB 
          -> Seq Scan on dt_voltage nx_4 (cost=0.00..1.02 rows=2 width=92) (actual time=0.001..0.001 rows=2 loops=1) 
    -> Hash (cost=2.13..2.13 rows=2 width=96) (actual time=0.011..0.011 rows=2 loops=1) 
     Buckets: 1024 Batches: 1 Memory Usage: 1kB 
     -> Hash Anti Join (cost=1.07..2.13 rows=2 width=96) (actual time=0.009..0.010 rows=2 loops=1) 
       Hash Cond: (e.hive = nx_3.hive) 
       Join Filter: (nx_3.instant > e.instant) 
       Rows Removed by Join Filter: 3 
       -> Seq Scan on dt_rain e (cost=0.00..1.03 rows=3 width=96) (actual time=0.001..0.002 rows=3 loops=1) 
       -> Hash (cost=1.03..1.03 rows=3 width=92) (actual time=0.002..0.002 rows=3 loops=1) 
        Buckets: 1024 Batches: 1 Memory Usage: 1kB 
        -> Seq Scan on dt_rain nx_3 (cost=0.00..1.03 rows=3 width=92) (actual time=0.001..0.001 rows=3 loops=1) 
Total runtime: 3488.684 ms 

此提出的版本是多少好多了。仍然有一些順序掃描。沒有他們,這種觀點將成爲一種純粹的藝術!

+0

通過相應的「NOT EXISTS(...)'構造來代替'MAX(...)'。並添加一個索引'ON dt_inout_summary(hive,即時DESC)'也適用於其他子表。並且請將'EXPLAIN ANALYZE'的輸出添加到您的問題中。圖形看起來很性感,但是相對沒用。 – joop 2014-09-23 13:01:57

+0

你的意思是** SELECT hive,instant,「input」,「output」,timeout FROM dt_inout_summary x WHERE x.hive = hive AND NOT EXISTS(SELECT hive,instant,「input」,「output」,timeout FROM dt_inout_summary x1 WHERE x.instant Azathoth 2014-09-23 14:26:21

+0

是的。 (但你似乎有錯誤的方式)Plus:你需要(合成)索引)另外:在graphc計劃中,主配置表被分類兩次並且自加入。不適合你的query.PLUS'解釋ANALYZE;',請。 – joop 2014-09-23 14:33:25

回答

1

這是NOT EXISTS(...)結構,它避免子查詢中的聚合max()。這將受益於綜合指數的presense ON dt_inout_summary(hive, instant DESC)

... 
FROM hives h 
LEFT OUTER JOIN (
    SELECT hive, instant, "input", "output", timeout FROM dt_inout_summary x 
     WHERE NOT EXISTS(
      SELECT 1 
      FROM dt_inout_summary nx 
      WHERE nx.hive = x.hive 
      AND nx.instant > x.instant 
     ) 
    ) b ON (h.id = x.hive) 
... 

BTW:你不需要的子查詢,只是一個普通的LEFT JOIN會做同樣的:

... 
FROM hives h 
LEFT JOIN dt_inout_summary x ON x.hive = h.id 
    AND NOT EXISTS(
     SELECT 1 
     FROM dt_inout_summary nx 
     WHERE nx.hive = x.hive 
     AND nx.instant > x.instant 
     ) 
... 

,但你會那麼必須引用主查詢中的x.yyyyy字段(... x.hive, x.instant, x."input", x."output", x.timeout

更新:查詢需要13(1 + 2 * 6)個條目範圍表條目。這可能會導致優化器退出。 你可以嘗試添加

SET join_collapse_limit = 16; 

您查詢之前。另一種方法是將所述子查詢分離到的CTE(熱膨脹係數是由優化破碎),但熱膨脹係數可以比對應的子查詢慢一點:

CREATE OR REPLACE VIEW dt_last4cte AS 
WITH cte_b AS (
    SELECT * 
    FROM dt_inout_summary b WHERE NOT EXISTS (SELECT 1 
     FROM dt_inout_summary nx 
     WHERE nx.hive = b.hive AND nx.instant > b.instant) 
     ) 
, cte_c AS (
    SELECT * 
    FROM dt_temperature c WHERE NOT EXISTS (SELECT 1 
     FROM dt_temperature nx 
     WHERE nx.hive = c.hive AND nx.instant > c.instant) 
     ) 
, cte_d AS (
    SELECT * 
    FROM dt_weight d WHERE NOT EXISTS (SELECT 1 
     FROM dt_weight nx WHERE nx.hive = d.hive AND nx.instant > d.instant) 
    ) 
, cte_e AS (
    SELECT * 
    FROM dt_rain e WHERE NOT EXISTS (SELECT 1 
     FROM dt_rain nx WHERE nx.hive = e.hive AND nx.instant > e.instant) 
    ) 
, cte_f AS (
    SELECT * 
    FROM dt_voltage f WHERE NOT EXISTS (SELECT 1 
     FROM dt_voltage nx WHERE nx.hive = f.hive AND nx.instant > f.instant) 
    ) 
, cte_g AS (
    SELECT * 
    FROM dt_gps g WHERE NOT EXISTS (SELECT 1 
     FROM dt_gps nx WHERE nx.hive = g.hive AND nx.instant > g.instant) 
    ) 
SELECT h0.id AS hive, 
    b.instant AS inout_instant, 
    b.input, 
    b.output, 
    b.timeout, 
    c.instant AS temperature_instant, 
    c.internal, 
    c.external, 
    d.instant AS weight_instant, 
    d.weight, 
    e.instant AS rain_instant, 
    e.rain, 
    f.instant AS voltage_instant, 
    f.operational, 
    f.panel, 
    f.cell, 
    g.instant AS gps_instant, 
    g.latitude, 
    g.longitude, 
    g.altitude 
    FROM hives h0 
    LEFT JOIN cte_b b ON b.hive = h0.id 
    LEFT JOIN cte_c c ON c.hive = h0.id 
    LEFT JOIN cte_d d ON d.hive = h0.id 
    LEFT JOIN cte_e e ON e.hive = h0.id 
    LEFT JOIN cte_f f ON f.hive = h0.id 
    LEFT JOIN cte_g g ON g.hive = h0.id 
    -- WHERE __aditional__conditions__ 
    ; 

如果視圖的典型用法將附加條件添加到得到的最終查詢中,優化程序將選擇更具選擇性的計劃可能

+0

應用此解決方案並進行相應更新。非常好,乾淨。現在好多了,但還是有一些順序掃描,選擇仍然需要幾秒鐘才能完成。 – Azathoth 2014-09-23 16:53:27

+0

你是否在所有桌子上都進行過真空分析? BTW:seq掃描並不總是不好。有時他們甚至是最好的人可以期望的。 – joop 2014-09-23 17:03:42

+0

是的,我保留了大約3/4秒。爲每個表格和每個配置單元做一個單獨的查詢仍然更快(假設每頁最多顯示10個配置單元) – Azathoth 2014-09-23 18:31:55