2017-11-26 16 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 초의 시간이 너무 많이 걸리며 모든 경로가 포함되어 있지 않습니다 (하나의 기기에서 85758을 선택하므로 하루에 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 행이 있습니다. 친구, 저에게 메일 보내주세요.이 선택 또는보기를 최적화하는 방법은 무엇입니까? 나는 때문에 VIEW의 분석 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

뷰를 기반으로 선택을위한 실행 계획을 절대 생성 할 수 있습니다 (차이는 없습니다) –

답변

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 경로 시작은입니다. eventid = 11이고 입력 모드 2가 반환됩니다. route의 중지는 eventid = 11이고 mod 2가 0을 입력 할 때입니다. –

+0

쿼리에서 'ORDER BY 입력'대신 'ORDER BY MOD (입력 2) DESC'를 시도하십시오. 위. ** 나는 어떤 데이터도 볼 수 없어 눈 가리개로 작업 중입니다 ** ** –

+0

정보를 제공해 주셔서 감사합니다. 그러나 여전히 길 찾기가 잘못된 날짜입니다. 이미지를 참조하십시오 : https://imgur.com/a/7tfmn 위의 예를 삽입했습니다. 귀하의 선택은 내가 파란색으로 "귀하의 정류장"으로 표시하지만 적색의 "정지"근처에있는 날짜를 얻고 싶었던 경로의 정지를 감지했습니다. 경로의 시작을 감지하는 것이 좋습니다. :) –