2017-11-26 8 views
-1

私は経路履歴を意味するという名前のビューHistoriaTrasを作成しました。VIEWまたはSELECTを最適化するにはどうすればよいですか?

CREATE VIEW historiatras AS 
SELECT 
DataRozpoczeciaTrasy.deviceid AS deviceid, 
DataZakonczeniaTrasy.ts - DataRozpoczeciaTrasy.ts AS RoznicaCzasu, 
DataRozpoczeciaTrasy.ts AS RozpoczecieTrasy, DataZakonczeniaTrasy.ts AS ZakonczenieTrasy 
FROM DEVICE_DATA DataRozpoczeciaTrasy 
JOIN DEVICE_DATA DataZakonczeniaTrasy ON DataRozpoczeciaTrasy.deviceid = DataZakonczeniaTrasy.deviceid AND mod(DataZakonczeniaTrasy.inputs,2)=0 AND DataZakonczeniaTrasy.eventid = 11 AND DataZakonczeniaTrasy.ts > DataRozpoczeciaTrasy.ts 
WHERE mod(DataRozpoczeciaTrasy.inputs,2)=1 
AND DataRozpoczeciaTrasy.eventid = 11 

TS =タイムスタンプは
開始ルートの DataRozpoczeciaTrasy =日付
ストップルートDataRozpoczeciaTrasy間
RoznicaCzasu =時間の DataZakonczeniaTrasy =日 - 私は下に作るすべてのものを選択した場合DataZakonczeniaTrasy

はほとんど良い作品が、それは取ります〜27秒の時間がかかりすぎて、すべてのルートが含まれていません(1日から1つのデバイス(85758)から選択するため):

SELECT * FROM HistoriaTras Trasy 
WHERE RoznicaCzasu = (SELECT MIN(Trasy1.RoznicaCzasu) 
         FROM HistoriaTras Trasy1 
         WHERE Trasy.RozpoczecieTrasy = Trasy1.RozpoczecieTrasy) 
    AND deviceid = 85758 
    AND RozpoczecieTrasy > '2017-11-05 00:00:00' 
    AND RozpoczecieTrasy < '2017-11-06 00:00:00' 

私が削除した場合:

AND deviceid = 85758 AND RozpoczecieTrasy > '2017-11-05 00:00:00' AND RozpoczecieTrasy < '2017-11-06 00:00:00' 

をそれは...あまりにも多くの時間がかかります。私はそれをテストしなかったが、それは時間がかかりすぎる。

device_dataテーブルには約100k行あります。 友人、私に書きなさいこの選択または表示を最適化するにはどうすればよいですか?私は私があるため、ビューの分析SELECTの分析を説明貼り付けています

が許可されていないPostgreSQLの10を使用しています:

Nested Loop (cost=0.00..21281.66 rows=1 width=40) (actual time=3973.445..982716.756 rows=380 loops=1) 
    Join Filter: ((datazakonczeniatrasy.ts > datarozpoczeciatrasy.ts) AND (datarozpoczeciatrasy.deviceid = datazakonczeniatrasy.deviceid) AND ((datazakonczeniatrasy.ts - datarozpoczeciatrasy.ts) = (SubPlan 1))) 
    Rows Removed by Join Filter: 142880 
    -> Seq Scan on device_data datarozpoczeciatrasy (cost=0.00..5259.22 rows=1 width=16) (actual time=0.046..17.667 rows=380 loops=1) 
     Filter: ((eventid = '11'::numeric) AND (mod(inputs, '2'::numeric) = '1'::numeric)) 
     Rows Removed by Filter: 97518 
    -> Seq Scan on device_data datazakonczeniatrasy (cost=0.00..5259.22 rows=1 width=16) (actual time=0.011..17.850 rows=377 loops=380) 
     Filter: ((eventid = '11'::numeric) AND (mod(inputs, '2'::numeric) = '0'::numeric)) 
     Rows Removed by Filter: 97521 
    SubPlan 1 
    -> Aggregate (cost=10763.19..10763.20 rows=1 width=16) (actual time=34.834..34.834 rows=1 loops=28011) 
      -> Nested Loop (cost=0.00..10763.19 rows=1 width=16) (actual time=9.246..34.805 rows=112 loops=28011) 
       Join Filter: ((datazakonczeniatrasy_1.ts > datarozpoczeciatrasy_1.ts) AND (datarozpoczeciatrasy_1.deviceid = datazakonczeniatrasy_1.deviceid)) 
       Rows Removed by Join Filter: 270 
       -> Seq Scan on device_data datarozpoczeciatrasy_1 (cost=0.00..5503.96 rows=1 width=16) (actual time=5.930..17.172 rows=1 loops=28011) 
         Filter: ((eventid = '11'::numeric) AND (datarozpoczeciatrasy.ts = ts) AND (mod(inputs, '2'::numeric) = '1'::numeric)) 
         Rows Removed by Filter: 97897 
       -> Seq Scan on device_data datazakonczeniatrasy_1 (cost=0.00..5259.22 rows=1 width=16) (actual time=0.012..17.327 rows=377 loops=28407) 
         Filter: ((eventid = '11'::numeric) AND (mod(inputs, '2'::numeric) = '0'::numeric)) 
         Rows Removed by Filter: 97521 
Planning time: 0.699 ms 
Execution time: 982717.118 ms 

マイテーブル:

CREATE TABLE "public"."device_data" ( 
"deviceid" Bigint REFERENCES cars (deviceid), 
"ts" Timestamp Without Time Zone, 
"longitude" Double Precision, 
"lattitude" Double Precision, 
"speedgps" Numeric(5, 0), 
"heading" Numeric(5, 0), 
"altitude" Numeric(5, 0), 
"satelite" Numeric(3, 0), 
"eventid" Numeric(3, 0), 
"mileagegps" Numeric(20, 0), 
"inputs" Numeric(5, 0), 
"voltageanalog1" Numeric(4, 2), 
"voltageanalog2" Numeric(4, 2), 
"voltageanalog3" Numeric(4, 2), 
"voltageanalog4" Numeric(4, 2), 
"voltageanalog5" Numeric(4, 2), 
"outputs" Numeric(3, 0), 
"totaldistance" Numeric(20, 0), 
"totalfuel" Numeric(20, 0), 
"vehiclespeed" Numeric(5, 0), 
"enginespeed" Numeric(5, 0), 
"fuellevel" Numeric(5, 0), 
"fuelcons" Numeric(5, 0), 
"accelerator" Numeric(3, 0), 
"tachograph" Numeric(5, 0), 
"axleweight" Numeric(5, 0), 
"indicators" Numeric(10, 0), 
"drivercode" Numeric(20, 0), 
"wiretemp1" Double Precision, 
"wiretemp2" Double Precision, 
"wiretemp3" Double Precision, 
"wiretemp4" Double Precision, 
"wiretemp5" Double Precision, 
"wiretemp6" Double Precision, 
"fuelflag" Integer, 
"gsmsignal" SmallInt, 
"speedcan" Integer, 
"gsmoperator" Bigint, 
"totalidlefuel" Bigint, 
"fuellevelperc" Integer, 
"enginetemp" SmallInt, 
"enginetotalhours" Bigint, 
"engineidletime" Bigint, 
"oiltemp" SmallInt, 
"hydroiltemp" SmallInt, 
"wirecode1" Numeric(20, 0), 
"wirecode2" Numeric(20, 0), 
"wirecode3" Numeric(20, 0), 
"wirecode4" Numeric(20, 0), 
"wirecode5" Numeric(20, 0), 
"wirecode6" Numeric(20, 0), 
"rapidpedalpress" Bigint, 
"rapidaccel" Bigint, 
"rapidbreak" Bigint, 
"engineoverspeed" Bigint, 
"torgue" SmallInt, 
"drivetimeoverspeedlimit0x12" Bigint, 
"drivetimeoverspeedlimit0x13" Bigint, 
"driver1idcard" Numeric(20, 0), 
"driver2idcard" Numeric(20, 0), 
"x3d" SmallInt, 
"y3d" SmallInt, 
"z3d" SmallInt, 
"axleweight1" Integer, 
"axleweight2" Integer, 
"axleweight3" Integer, 
"axleweight4" Integer); 
+1

'analyze HistoriaTras;'を実行します。その後、 'explain analyze your_query'を実行し、その出力をあなたの質問に貼り付けます。また、postgresqlパフォーマンスタグの[info link](https://stackoverflow.com/tags/postgresql-performance/info)も参照してください。 –

+0

ありがとうございました。 VIEWの解析は仮想テーブルであるため許可されていないため、SELECTの解析を貼り付けました。 –

+0

ビューに基づいてselectの実行計画を絶対に生成することはできますが(違いはありません) –

答えて

0

私は「窓関数」を使用することをお勧めMOD()を使用する自己結合の代わりにLEAD()を使用してください。

SELECT 
     d.deviceid  AS deviceid 
    , d.ts - d.lead_ts AS roznicaczasu 
    , d.ts    AS rozpoczecietrasy 
    , d.lead_ts  AS zakonczenietrasy 
FROM (
     SELECT 
      deviceid 
      , ts 
      , case when MOD(Inputs,2) = 1 
       then LEAD(ts) OVER (PARTITION BY deviceid, eventid 
            ORDER BY inputs DESC) 
      end AS lead_ts 
     FROM DEVICE_DATA 
     WHERE eventid = 11 
    ) d 
WHERE d.lead_ts IS NOT NULL 
; 
+0

あなたの提案はほとんどうまくいきましたが、今では開始ルートの日付が停止ルートの日付より遅い場合があります。 https://imgur.com/a/K8n3P ルートの開始は0の場合はidid = 11、入力モード2の場合は1を返します。routeの終了はeventid = 11の場合で、mod 2が0を入力した場合です。 –

+0

クエリのORDER BY入力ではなく、このORDER BY MOD(入力、2)DESCを試してください。上記。 **目に見えないデータがあるので、私は目隠しをしています** –

+0

ありがとうございます。画像をご覧ください: https://imgur.com/a/7tfmn 私は上記の例を挿入しました。あなたの選択は、私が青色の "あなたのストップ"とマークしたルートの停止を検出しましたが、赤色の "停止"に近い日付を取得したいと思います。経路の開始を検出することはOKです。 :) –

関連する問題