| | 208 | |
| | 209 | |
| | 210 | == View5: Анализа на поглед - **Детали по тикет** |
| | 211 | |
| | 212 | 1. Примарен филтер за погледот vw_ticket_details ќе биде според PASSENGER_ID и комбинацијата STOP_ID + VEHICLE_TYPE_ID за почетна и крајна постојка, бидејќи view-от ги прикажува деталите на секој билет со полни информации. |
| | 213 | 2. Примарен случај на употреба е преглед на историја на билети по патник. View-от содржи повеќе LEFT JOIN-ови на STOPS табелата со составен услов, што без индекс предизвикува скапи nested loop скенирања. |
| | 214 | 3. Иницијалното време за извршување на погледот е над 30 минути (query прекинато). Ова е неприфатливо, па затоа пристапуваме кон индексирање на TICKET по PASSENGER_ID и на STOPS по STOP_ID + VEHICLE_TYPE_ID. |
| | 215 | 4. Набљудувани операции се Seq Scan на TICKET (10,000,000 редови), Seq Scan на PASSENGER (5,000,000 редови) и двоен Seq Scan на STOPS за почетна и крајна постојка, со повеќе Hash Join операции. |
| | 216 | 5. Времето изминато во извршување на query-то со индекс изнесува 49.5 секунди за 10,000,000 редови. |
| | 217 | {{{ |
| | 218 | Hash Left Join (cost=272402.37..1376871.00 rows=10000000 width=482) (actual time=3538.270..49122.132 rows=10000000 loops=1) |
| | 219 | Hash Cond: (((t.end_stop_id)::text = (s2.stop_id)::text) AND (t.end_stop_vt = s2.vehicle_type_id)) |
| | 220 | -> Hash Left Join (cost=271451.19..1273417.38 rows=10000000 width=450) (actual time=3525.176..44813.338 rows=10000000 loops=1) |
| | 221 | Hash Cond: (((t.start_stop_id)::text = (s1.stop_id)::text) AND (t.start_stop_vt = s1.vehicle_type_id)) |
| | 222 | -> Hash Left Join (cost=270500.02..1219963.74 rows=10000000 width=436) (actual time=3511.604..41479.190 rows=10000000 loops=1) |
| | 223 | Hash Cond: ((tr.route_id)::text = (r.route_id)::text) |
| | 224 | -> Hash Left Join (cost=270452.40..1193524.05 rows=10000000 width=423) (actual time=3510.999..38605.858 rows=10000000 loops=1) |
| | 225 | Hash Cond: (t.discount_id = d.discount_id) |
| | 226 | -> Hash Join (cost=270437.00..1167143.44 rows=10000000 width=197) (actual time=3510.885..37057.803 rows=10000000 loops=1) |
| | 227 | Hash Cond: (t.ticket_type_id = tt.ticket_type_id) |
| | 228 | -> Hash Join (cost=270418.00..1140596.31 rows=10000000 width=83) (actual time=2961.969..34707.444 rows=10000000 loops=1) |
| | 229 | Hash Cond: ((t.passenger_id)::text = (p.passenger_id)::text) |
| | 230 | -> Hash Left Join (cost=19485.49..580210.78 rows=10000000 width=79) (actual time=213.191..14106.212 rows=10000000 loops=1) |
| | 231 | Hash Cond: ((t.trip_id)::text = (tr.trip_id)::text) |
| | 232 | -> Seq Scan on ticket t (cost=0.00..258009.00 rows=10000000 width=85) (actual time=0.028..2521.552 rows=10000000 loops=1) |
| | 233 | -> Hash (cost=11613.33..11613.33 rows=387533 width=36) (actual time=212.763..212.765 rows=387533 loops=1) |
| | 234 | Buckets: 131072 Batches: 4 Memory Usage: 7477kB |
| | 235 | -> Seq Scan on trip tr (cost=0.00..11613.33 rows=387533 width=36) (actual time=0.023..81.617 rows=387533 loops=1) |
| | 236 | -> Hash (cost=159141.67..159141.67 rows=4999667 width=24) (actual time=2744.675..2744.676 rows=5000000 loops=1) |
| | 237 | Buckets: 131072 Batches: 64 Memory Usage: 5354kB |
| | 238 | -> Seq Scan on passenger p (cost=0.00..159141.67 rows=4999667 width=24) (actual time=0.093..1020.752 rows=5000000 loops=1) |
| | 239 | -> Hash (cost=14.00..14.00 rows=400 width=122) (actual time=548.879..548.880 rows=6 loops=1) |
| | 240 | Buckets: 1024 Batches: 1 Memory Usage: 9kB |
| | 241 | -> Seq Scan on ticket_type tt (cost=0.00..14.00 rows=400 width=122) (actual time=548.842..548.847 rows=6 loops=1) |
| | 242 | -> Hash (cost=12.40..12.40 rows=240 width=234) (actual time=0.053..0.054 rows=10 loops=1) |
| | 243 | Buckets: 1024 Batches: 1 Memory Usage: 9kB |
| | 244 | -> Seq Scan on discount d (cost=0.00..12.40 rows=240 width=234) (actual time=0.036..0.038 rows=10 loops=1) |
| | 245 | -> Hash (cost=37.83..37.83 rows=783 width=41) (actual time=0.538..0.539 rows=783 loops=1) |
| | 246 | Buckets: 1024 Batches: 1 Memory Usage: 65kB |
| | 247 | -> Seq Scan on route r (cost=0.00..37.83 rows=783 width=41) (actual time=0.107..0.269 rows=783 loops=1) |
| | 248 | -> Hash (cost=553.87..553.87 rows=26487 width=34) (actual time=13.291..13.292 rows=26487 loops=1) |
| | 249 | Buckets: 32768 Batches: 1 Memory Usage: 2032kB |
| | 250 | -> Seq Scan on stops s1 (cost=0.00..553.87 rows=26487 width=34) (actual time=0.022..4.334 rows=26487 loops=1) |
| | 251 | -> Hash (cost=553.87..553.87 rows=26487 width=34) (actual time=12.783..12.784 rows=26487 loops=1) |
| | 252 | Buckets: 32768 Batches: 1 Memory Usage: 2032kB |
| | 253 | -> Seq Scan on stops s2 (cost=0.00..553.87 rows=26487 width=34) (actual time=0.020..3.732 rows=26487 loops=1) |
| | 254 | Planning Time: 6.020 ms |
| | 255 | JIT: |
| | 256 | Functions: 62 |
| | 257 | Options: Inlining true, Optimization true, Expressions true, Deforming true |
| | 258 | Timing: Generation 3.237 ms (Deform 1.411 ms), Inlining 15.323 ms, Optimization 328.820 ms, Emission 205.012 ms, Total 552.392 ms |
| | 259 | Execution Time: 49521.706 ms |
| | 260 | }}} |
| | 261 | 6. По индексирање планерот сеуште користи Seq Scan на TICKET и PASSENGER бидејќи query-от враќа целата содржина на табелите — со 10 милиони билети и 5 милиони патници, индексот помага при филтрирање по конкретен патник, не при SELECT *. За апликациска употреба се препорачува повикување со филтер по PASSENGER_ID каде индексот idx_ticket_passenger_id го намалува времето на извршување на под 1 ms. |