| 462 | | sh.stock_id, |
| 463 | | sh.price, |
| 464 | | (sh.price - LAG(sh.price) OVER ( |
| 465 | | PARTITION BY sh.stock_id ORDER BY sh.timestamp)) |
| 466 | | / NULLIF(LAG(sh.price) OVER ( |
| 467 | | PARTITION BY sh.stock_id ORDER BY sh.timestamp), 0) AS daily_return |
| 468 | | FROM stock_history sh |
| 469 | | WHERE sh.timestamp >= '2024-01-01' |
| 470 | | AND sh.timestamp <= '2024-12-31'; |
| 471 | | |
| 472 | | QUERY PLAN | |
| 473 | | ---------------------------------------------------------------------------------------------------------------------------------+ |
| 474 | | WindowAgg (cost=8773.08..9784.81 rows=36791 width=28) (actual time=41.592..66.876 rows=36600 loops=1) | |
| 475 | | -> Sort (cost=8773.06..8865.03 rows=36791 width=20) (actual time=41.543..46.298 rows=36600 loops=1) | |
| 476 | | Sort Key: stock_id, "timestamp" | |
| 477 | | Sort Method: external merge Disk: 1256kB | |
| 478 | | -> Seq Scan on stock_history sh (cost=0.00..4471.00 rows=36791 width=20) (actual time=0.060..22.078 rows=36600 loops=1)| |
| 479 | | Filter: (("timestamp" >= '2024-01-01'::date) AND ("timestamp" <= '2024-12-31'::date)) | |
| 480 | | Rows Removed by Filter: 163400 | |
| 481 | | Planning Time: 0.526 ms | |
| 482 | | Execution Time: 69.235 ms | |
| | 523 | s.id, |
| | 524 | s.symbol, |
| | 525 | s.name, |
| | 526 | s.current_price, |
| | 527 | COALESCE(ps.ps_min_price, s.current_price), |
| | 528 | COALESCE(ps.ps_max_price, s.current_price), |
| | 529 | ROUND( |
| | 530 | ( |
| | 531 | (COALESCE(ps.ps_max_price, s.current_price) |
| | 532 | - COALESCE(ps.ps_min_price, s.current_price)) |
| | 533 | / NULLIF(COALESCE(ps.ps_min_price, s.current_price), 0) * 100 |
| | 534 | )::NUMERIC |
| | 535 | , 2), |
| | 536 | COALESCE(ps.ps_avg_price, s.current_price), |
| | 537 | COALESCE(ps.ps_volatility_pct, 0), |
| | 538 | COALESCE(ps.ps_total_points, 0), |
| | 539 | COALESCE(ts.ts_total_volume, 0), |
| | 540 | COALESCE(ts.ts_total_count, 0), |
| | 541 | COALESCE(ts.ts_buy_count, 0), |
| | 542 | COALESCE(ts.ts_sell_count, 0), |
| | 543 | ROUND( |
| | 544 | (COALESCE(ts.ts_buy_count, 0)::NUMERIC |
| | 545 | / NULLIF(COALESCE(ts.ts_sell_count, 0), 0)) |
| | 546 | , 2), |
| | 547 | COALESCE(ws.ws_active_watchers, 0), |
| | 548 | COALESCE(pst.pst_pending_count, 0), |
| | 549 | CASE |
| | 550 | WHEN tc.tc_slope > 0.01 THEN 'UPTREND' |
| | 551 | WHEN tc.tc_slope < -0.01 THEN 'DOWNTREND' |
| | 552 | ELSE 'SIDEWAYS' |
| | 553 | END, |
| | 554 | COALESCE(tc.tc_slope, 0), |
| | 555 | ROUND( |
| | 556 | (COALESCE(ws.ws_active_watchers, 0) * 2.0 |
| | 557 | + COALESCE(ts.ts_total_count, 0) * 1.0 |
| | 558 | + COALESCE(pst.pst_pending_count, 0) * 3.0) |
| | 559 | , 2), |
| | 560 | RANK() OVER (ORDER BY COALESCE(ps.ps_volatility_pct, 0) DESC), |
| | 561 | RANK() OVER (ORDER BY ( |
| | 562 | COALESCE(ws.ws_active_watchers, 0) * 2.0 |
| | 563 | + COALESCE(ts.ts_total_count, 0) |
| | 564 | + COALESCE(pst.pst_pending_count, 0) * 3.0 |
| | 565 | ) DESC) |
| | 566 | FROM stock s |
| | 567 | LEFT JOIN price_stats ps ON s.id = ps.ps_stock_id |
| | 568 | LEFT JOIN trend_calc tc ON s.id = tc.tc_stock_id |
| | 569 | LEFT JOIN txn_stats ts ON s.id = ts.ts_stock_id |
| | 570 | LEFT JOIN watchlist_stats ws ON s.id = ws.ws_stock_id |
| | 571 | LEFT JOIN pending_stats pst ON s.id = pst.pst_stock_id |
| | 572 | ORDER BY ps.ps_volatility_pct DESC; |
| | 573 | |
| | 574 | |
| | 575 | |
| | 576 | QUERY PLAN | |
| | 577 | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ |
| | 578 | Sort (cost=50000113394.02..50000113394.27 rows=100 width=338) (actual time=1981.897..1981.915 rows=100 loops=1) | |
| | 579 | Sort Key: (COALESCE((stddev((((sh.price - lag(sh.price) OVER (?)) / NULLIF(lag(sh.price) OVER (?), '0'::double precision)))) * '100'::double precision), '0'::double precision)) DESC | |
| | 580 | Sort Method: quicksort Memory: 46kB | |
| | 581 | -> WindowAgg (cost=50000113381.71..50000113390.70 rows=100 width=338) (actual time=1981.413..1981.748 rows=100 loops=1) | |
| | 582 | -> Sort (cost=50000113381.70..50000113381.95 rows=100 width=202) (actual time=1981.382..1981.402 rows=100 loops=1) | |
| | 583 | Sort Key: (COALESCE((COALESCE((stddev((((sh.price - lag(sh.price) OVER (?)) / NULLIF(lag(sh.price) OVER (?), '0'::double precision)))) * '100'::double precision), '0'::double precision)), '0'::double precision)) DESC| |
| | 584 | Sort Method: quicksort Memory: 39kB | |
| | 585 | -> WindowAgg (cost=50000113374.89..50000113378.37 rows=100 width=202) (actual time=1981.205..1981.305 rows=100 loops=1) | |
| | 586 | -> Sort (cost=50000113374.87..50000113375.12 rows=100 width=194) (actual time=1981.148..1981.166 rows=100 loops=1) | |
| | 587 | Sort Key: (((((COALESCE((count(DISTINCT w.user_id)), '0'::bigint))::numeric * 2.0) + (COALESCE((count(*)), '0'::bigint))::numeric) + ((COALESCE((count(tr.id)), '0'::bigint))::numeric * 3.0))) DESC | |
| | 588 | Sort Method: quicksort Memory: 38kB | |
| | 589 | -> Merge Left Join (cost=50000082962.33..50000113371.55 rows=100 width=194) (actual time=1674.083..1980.884 rows=100 loops=1) | |
| | 590 | Merge Cond: (s.id = s_1.id) | |
| | 591 | -> Merge Left Join (cost=40000082962.19..40000107889.58 rows=100 width=146) (actual time=1671.513..1933.067 rows=100 loops=1) | |
| | 592 | Merge Cond: (s.id = w.stock_id) | |
| | 593 | -> Merge Left Join (cost=30000080823.42..30000105599.91 rows=100 width=138) (actual time=1657.677..1914.227 rows=100 loops=1) | |
| | 594 | Merge Cond: (s.id = t.stock_id) | |
| | 595 | -> Merge Left Join (cost=20000058569.46..20000079595.67 rows=100 width=106) (actual time=1506.027..1762.509 rows=100 loops=1) | |
| | 596 | Merge Cond: (s.id = sh_1.stock_id) | |
| | 597 | -> Merge Left Join (cost=10000029284.80..10000039803.53 rows=100 width=74) (actual time=1355.378..1508.374 rows=100 loops=1) | |
| | 598 | Merge Cond: (s.id = sh.stock_id) | |
| | 599 | -> Index Scan using stock_pkey on stock s (cost=0.14..14.64 rows=100 width=34) (actual time=0.031..0.094 rows=100 loops=1) | |
| | 600 | -> GroupAggregate (cost=10000029284.66..10000039786.39 rows=100 width=48) (actual time=167.128..319.895 rows=100 loops=1) | |
| | 601 | Group Key: sh.stock_id | |
| | 602 | -> WindowAgg (cost=10000029284.66..10000034784.64 rows=200000 width=28) (actual time=165.583..292.548 rows=200000 loops=1) | |
| | 603 | -> Sort (cost=10000029284.64..10000029784.64 rows=200000 width=20) (actual time=165.491..192.959 rows=200000 loops=1) | |
| | 604 | Sort Key: sh.stock_id, sh."timestamp" | |
| | 605 | Sort Method: external merge Disk: 6680kB | |
| | 606 | -> Seq Scan on stock_history sh (cost=10000000000.00..10000003471.00 rows=200000 width=20) (actual time=0.126..33.684 rows=200000 loops=1) | |
| | 607 | -> GroupAggregate (cost=10000029284.66..10000039789.64 rows=100 width=40) (actual time=150.618..253.952 rows=100 loops=1) | |
| | 608 | Group Key: sh_1.stock_id | |
| | 609 | -> WindowAgg (cost=10000029284.66..10000033284.64 rows=200000 width=28) (actual time=149.544..233.175 rows=200000 loops=1) | |
| | 610 | -> Sort (cost=10000029284.64..10000029784.64 rows=200000 width=20) (actual time=149.487..176.585 rows=200000 loops=1) | |
| | 611 | Sort Key: sh_1.stock_id, sh_1."timestamp" | |
| | 612 | Sort Method: external merge Disk: 6680kB | |
| | 613 | -> Seq Scan on stock_history sh_1 (cost=10000000000.00..10000003471.00 rows=200000 width=20) (actual time=0.025..20.128 rows=200000 loops=1) | |
| | 614 | -> GroupAggregate (cost=10000022253.95..10000026003.96 rows=1 width=40) (actual time=151.624..151.625 rows=1 loops=1) | |
| | 615 | Group Key: t.stock_id | |
| | 616 | -> Sort (cost=10000022253.95..10000022628.95 rows=150000 width=24) (actual time=107.994..127.905 rows=150000 loops=1) | |
| | 617 | Sort Key: t.stock_id | |
| | 618 | Sort Method: external merge Disk: 5096kB | |
| | 619 | -> Seq Scan on transactions t (cost=10000000000.00..10000003205.00 rows=150000 width=24) (actual time=0.081..32.995 rows=150000 loops=1) | |
| | 620 | -> GroupAggregate (cost=10000002138.77..10000002288.97 rows=20 width=16) (actual time=13.812..18.748 rows=20 loops=1) | |
| | 621 | Group Key: w.stock_id | |
| | 622 | -> Sort (cost=10000002138.77..10000002188.77 rows=20000 width=16) (actual time=13.523..16.642 rows=20000 loops=1) | |
| | 623 | Sort Key: w.stock_id, w.user_id | |
| | 624 | Sort Method: external merge Disk: 512kB | |
| | 625 | -> Seq Scan on watchlist w (cost=10000000000.00..10000000367.00 rows=20000 width=16) (actual time=0.044..3.934 rows=20000 loops=1) | |
| | 626 | -> GroupAggregate (cost=10000000000.14..10000005477.72 rows=100 width=16) (actual time=2.541..47.575 rows=100 loops=1) | |
| | 627 | Group Key: s_1.id | |
| | 628 | -> Nested Loop (cost=10000000000.14..10000005459.00 rows=3544 width=16) (actual time=0.120..47.189 rows=3544 loops=1) | |
| | 629 | Join Filter: ((s_1.symbol)::text = (tr.stock_symbol)::text) | |
| | 630 | Rows Removed by Join Filter: 350856 | |
| | 631 | -> Index Scan using stock_pkey on stock s_1 (cost=0.14..14.64 rows=100 width=13) (actual time=0.033..0.347 rows=100 loops=1) | |
| | 632 | -> Materialize (cost=10000000000.00..10000000137.22 rows=3544 width=13) (actual time=0.001..0.190 rows=3544 loops=100) | |
| | 633 | -> Seq Scan on trade_request tr (cost=10000000000.00..10000000119.50 rows=3544 width=13) (actual time=0.065..1.321 rows=3544 loops=1) | |
| | 634 | Filter: ((status)::text = 'PENDING'::text) | |
| | 635 | Rows Removed by Filter: 1456 | |
| | 636 | Planning Time: 5.352 ms | |
| | 637 | JIT: | |
| | 638 | Functions: 72 | |
| | 639 | Options: Inlining true, Optimization true, Expressions true, Deforming true | |
| | 640 | Timing: Generation 9.390 ms (Deform 3.248 ms), Inlining 173.252 ms, Optimization 557.229 ms, Emission 458.237 ms, Total 1198.107 ms | |
| | 641 | Execution Time: 2034.799 ms | |
| | 642 | |
| 500 | | SELECT ... |
| 501 | | |
| 502 | | |
| 503 | | QUERY PLAN | |
| 504 | | -------------------------------------------------------------------------------------------------------------------------------------------------------------+ |
| 505 | | WindowAgg (cost=0.55..9020.40 rows=36500 width=28) (actual time=0.061..39.845 rows=36600 loops=1) | |
| 506 | | -> Index Scan using idx_sh_stock_id_timestamp on stock_history sh (cost=0.42..8120.30 rows=36500 width=20) (actual time=0.048..16.502 rows=36600 loops=1)| |
| 507 | | Index Cond: (("timestamp" >= '2024-01-01'::date) AND ("timestamp" <= '2024-12-31'::date)) | |
| 508 | | Planning Time: 0.142 ms | |
| 509 | | Execution Time: 40.512 ms | |
| 510 | | |
| 511 | | }}} |
| 512 | | |
| | 660 | ... |
| | 661 | |
| | 662 | |
| | 663 | |
| | 664 | QUERY PLAN | |
| | 665 | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ |
| | 666 | Sort (cost=30000067769.58..30000067769.83 rows=100 width=338) (actual time=1676.027..1676.046 rows=100 loops=1) | |
| | 667 | Sort Key: (COALESCE((stddev((((sh.price - lag(sh.price) OVER (?)) / NULLIF(lag(sh.price) OVER (?), '0'::double precision)))) * '100'::double precision), '0'::double precision)) DESC | |
| | 668 | Sort Method: quicksort Memory: 46kB | |
| | 669 | -> WindowAgg (cost=30000067757.27..30000067766.25 rows=100 width=338) (actual time=1675.578..1675.913 rows=100 loops=1) | |
| | 670 | -> Sort (cost=30000067757.25..30000067757.50 rows=100 width=202) (actual time=1675.548..1675.566 rows=100 loops=1) | |
| | 671 | Sort Key: (COALESCE((COALESCE((stddev((((sh.price - lag(sh.price) OVER (?)) / NULLIF(lag(sh.price) OVER (?), '0'::double precision)))) * '100'::double precision), '0'::double precision)), '0'::double precision)) DESC| |
| | 672 | Sort Method: quicksort Memory: 39kB | |
| | 673 | -> WindowAgg (cost=30000067750.45..30000067753.93 rows=100 width=202) (actual time=1675.391..1675.492 rows=100 loops=1) | |
| | 674 | -> Sort (cost=30000067750.43..30000067750.68 rows=100 width=194) (actual time=1675.324..1675.341 rows=100 loops=1) | |
| | 675 | Sort Key: (((((COALESCE((count(DISTINCT w.user_id)), '0'::bigint))::numeric * 2.0) + (COALESCE((count(*)), '0'::bigint))::numeric) + ((COALESCE((count(tr.id)), '0'::bigint))::numeric * 3.0))) DESC | |
| | 676 | Sort Method: quicksort Memory: 38kB | |
| | 677 | -> Merge Left Join (cost=30000024393.95..30000067747.11 rows=100 width=194) (actual time=1319.475..1675.091 rows=100 loops=1) | |
| | 678 | Merge Cond: (s.id = s_1.id) | |
| | 679 | -> Merge Left Join (cost=20000024393.81..20000062265.14 rows=100 width=146) (actual time=1317.005..1627.105 rows=100 loops=1) | |
| | 680 | Merge Cond: (s.id = w.stock_id) | |
| | 681 | -> Merge Left Join (cost=10000022255.04..10000059975.47 rows=100 width=138) (actual time=1303.857..1608.799 rows=100 loops=1) | |
| | 682 | Merge Cond: (s.id = t.stock_id) | |
| | 683 | -> Merge Left Join (cost=1.09..33971.23 rows=100 width=106) (actual time=1155.604..1460.455 rows=100 loops=1) | |
| | 684 | Merge Cond: (s.id = sh_1.stock_id) | |
| | 685 | -> Merge Left Join (cost=0.61..16991.31 rows=100 width=74) (actual time=1154.257..1339.341 rows=100 loops=1) | |
| | 686 | Merge Cond: (s.id = sh.stock_id) | |
| | 687 | -> Index Scan using stock_pkey on stock s (cost=0.14..14.64 rows=100 width=34) (actual time=0.157..0.215 rows=100 loops=1) | |
| | 688 | -> GroupAggregate (cost=0.47..16974.17 rows=100 width=48) (actual time=2.079..186.903 rows=100 loops=1) | |
| | 689 | Group Key: sh.stock_id | |
| | 690 | -> WindowAgg (cost=0.47..11972.42 rows=200000 width=28) (actual time=0.172..158.424 rows=200000 loops=1) | |
| | 691 | -> Index Only Scan using idx_sh_stock_timestamp on stock_history sh (cost=0.42..6972.42 rows=200000 width=20) (actual time=0.124..43.800 rows=200000 loops=1) | |
| | 692 | Heap Fetches: 0 | |
| | 693 | -> GroupAggregate (cost=0.47..16977.42 rows=100 width=40) (actual time=1.320..120.928 rows=100 loops=1) | |
| | 694 | Group Key: sh_1.stock_id | |
| | 695 | -> WindowAgg (cost=0.47..10472.42 rows=200000 width=28) (actual time=0.031..99.876 rows=200000 loops=1) | |
| | 696 | -> Index Only Scan using idx_sh_stock_timestamp on stock_history sh_1 (cost=0.42..6972.42 rows=200000 width=20) (actual time=0.018..30.217 rows=200000 loops=1) | |
| | 697 | Heap Fetches: 0 | |
| | 698 | -> GroupAggregate (cost=10000022253.95..10000026003.96 rows=1 width=40) (actual time=148.227..148.228 rows=1 loops=1) | |
| | 699 | Group Key: t.stock_id | |
| | 700 | -> Sort (cost=10000022253.95..10000022628.95 rows=150000 width=24) (actual time=104.714..124.482 rows=150000 loops=1) | |
| | 701 | Sort Key: t.stock_id | |
| | 702 | Sort Method: external merge Disk: 5096kB | |
| | 703 | -> Seq Scan on transactions t (cost=10000000000.00..10000003205.00 rows=150000 width=24) (actual time=0.075..29.959 rows=150000 loops=1) | |
| | 704 | -> GroupAggregate (cost=10000002138.77..10000002288.97 rows=20 width=16) (actual time=13.124..18.215 rows=20 loops=1) | |
| | 705 | Group Key: w.stock_id | |
| | 706 | -> Sort (cost=10000002138.77..10000002188.77 rows=20000 width=16) (actual time=12.831..16.052 rows=20000 loops=1) | |
| | 707 | Sort Key: w.stock_id, w.user_id | |
| | 708 | Sort Method: external merge Disk: 512kB | |
| | 709 | -> Seq Scan on watchlist w (cost=10000000000.00..10000000367.00 rows=20000 width=16) (actual time=0.054..3.396 rows=20000 loops=1) | |
| | 710 | -> GroupAggregate (cost=10000000000.14..10000005477.72 rows=100 width=16) (actual time=2.438..47.689 rows=100 loops=1) | |
| | 711 | Group Key: s_1.id | |
| | 712 | -> Nested Loop (cost=10000000000.14..10000005459.00 rows=3544 width=16) (actual time=0.109..47.268 rows=3544 loops=1) | |
| | 713 | Join Filter: ((s_1.symbol)::text = (tr.stock_symbol)::text) | |
| | 714 | Rows Removed by Join Filter: 350856 | |
| | 715 | -> Index Scan using stock_pkey on stock s_1 (cost=0.14..14.64 rows=100 width=13) (actual time=0.040..0.293 rows=100 loops=1) | |
| | 716 | -> Materialize (cost=10000000000.00..10000000137.22 rows=3544 width=13) (actual time=0.001..0.190 rows=3544 loops=100) | |
| | 717 | -> Seq Scan on trade_request tr (cost=10000000000.00..10000000119.50 rows=3544 width=13) (actual time=0.047..1.240 rows=3544 loops=1) | |
| | 718 | Filter: ((status)::text = 'PENDING'::text) | |
| | 719 | Rows Removed by Filter: 1456 | |
| | 720 | Planning Time: 3.885 ms | |
| | 721 | JIT: | |
| | 722 | Functions: 68 | |
| | 723 | Options: Inlining true, Optimization true, Expressions true, Deforming true | |
| | 724 | Timing: Generation 4.970 ms (Deform 1.546 ms), Inlining 133.811 ms, Optimization 561.492 ms, Emission 457.098 ms, Total 1157.371 ms | |
| | 725 | Execution Time: 1720.407 ms | |
| | 726 | |
| | 727 | }}} |
| | 728 | |
| | 729 | idx_sh_stock_timestamp => Baseline: Seq Scan on stock_history + Sort Method: external merge Disk: 6680kB (два пати). Со индексот: Index Only Scan using idx_sh_stock_timestamp + Heap Fetches: 0 (два пати, за daily_returns и price_ordered). |
| 521 | | SELECT ... |
| 522 | | |
| 523 | | QUERY PLAN | |
| 524 | | -------------------------------------------------------------------------------------------------------------------------------------------------------------+ |
| 525 | | WindowAgg (cost=0.66..9098.75 rows=36545 width=28) (actual time=0.083..42.003 rows=36600 loops=1) | |
| 526 | | -> Index Scan using idx_sh_stock_id_timestamp on stock_history sh (cost=0.42..8185.12 rows=36545 width=20) (actual time=0.070..17.564 rows=36600 loops=1)| |
| 527 | | Index Cond: (("timestamp" >= '2024-01-01'::date) AND ("timestamp" <= '2024-12-31'::date)) | |
| 528 | | Planning Time: 0.162 ms | |
| 529 | | Execution Time: 43.946 ms | |
| 530 | | }}} |
| 531 | | |
| 532 | | не се користи |
| | 741 | ... |
| | 742 | |
| | 743 | QUERY PLAN | |
| | 744 | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ |
| | 745 | Sort (cost=20000049527.58..20000049527.83 rows=100 width=338) (actual time=1646.056..1646.190 rows=100 loops=1) | |
| | 746 | Sort Key: (COALESCE((stddev((((sh.price - lag(sh.price) OVER (?)) / NULLIF(lag(sh.price) OVER (?), '0'::double precision)))) * '100'::double precision), '0'::double precision)) DESC | |
| | 747 | Sort Method: quicksort Memory: 46kB | |
| | 748 | -> WindowAgg (cost=20000049515.28..20000049524.26 rows=100 width=338) (actual time=1645.651..1646.098 rows=100 loops=1) | |
| | 749 | -> Sort (cost=20000049515.26..20000049515.51 rows=100 width=202) (actual time=1645.616..1645.752 rows=100 loops=1) | |
| | 750 | Sort Key: (COALESCE((COALESCE((stddev((((sh.price - lag(sh.price) OVER (?)) / NULLIF(lag(sh.price) OVER (?), '0'::double precision)))) * '100'::double precision), '0'::double precision)), '0'::double precision)) DESC| |
| | 751 | Sort Method: quicksort Memory: 39kB | |
| | 752 | -> WindowAgg (cost=20000049508.46..20000049511.94 rows=100 width=202) (actual time=1645.448..1645.673 rows=100 loops=1) | |
| | 753 | -> Sort (cost=20000049508.44..20000049508.69 rows=100 width=194) (actual time=1645.383..1645.519 rows=100 loops=1) | |
| | 754 | Sort Key: (((((COALESCE((count(DISTINCT w.user_id)), '0'::bigint))::numeric * 2.0) + (COALESCE((count(*)), '0'::bigint))::numeric) + ((COALESCE((count(tr.id)), '0'::bigint))::numeric * 3.0))) DESC | |
| | 755 | Sort Method: quicksort Memory: 38kB | |
| | 756 | -> Merge Left Join (cost=20000003140.44..20000049505.12 rows=100 width=194) (actual time=1286.813..1645.278 rows=100 loops=1) | |
| | 757 | Merge Cond: (s.id = s_1.id) | |
| | 758 | -> Merge Left Join (cost=10000003140.30..10000044023.15 rows=100 width=146) (actual time=1284.382..1597.207 rows=100 loops=1) | |
| | 759 | Merge Cond: (s.id = w.stock_id) | |
| | 760 | -> Merge Left Join (cost=1001.53..41733.47 rows=100 width=138) (actual time=1271.103..1578.714 rows=100 loops=1) | |
| | 761 | Merge Cond: (s.id = t.stock_id) | |
| | 762 | -> Merge Left Join (cost=1.09..33971.23 rows=100 width=106) (actual time=1029.039..1336.446 rows=100 loops=1) | |
| | 763 | Merge Cond: (s.id = sh_1.stock_id) | |
| | 764 | -> Merge Left Join (cost=0.61..16991.31 rows=100 width=74) (actual time=1027.729..1214.561 rows=100 loops=1) | |
| | 765 | Merge Cond: (s.id = sh.stock_id) | |
| | 766 | -> Index Scan using stock_pkey on stock s (cost=0.14..14.64 rows=100 width=34) (actual time=0.078..0.129 rows=100 loops=1) | |
| | 767 | -> GroupAggregate (cost=0.47..16974.17 rows=100 width=48) (actual time=2.043..188.628 rows=100 loops=1) | |
| | 768 | Group Key: sh.stock_id | |
| | 769 | -> WindowAgg (cost=0.47..11972.42 rows=200000 width=28) (actual time=0.159..160.690 rows=200000 loops=1) | |
| | 770 | -> Index Only Scan using idx_sh_stock_timestamp on stock_history sh (cost=0.42..6972.42 rows=200000 width=20) (actual time=0.111..44.612 rows=200000 loops=1) | |
| | 771 | Heap Fetches: 0 | |
| | 772 | -> GroupAggregate (cost=0.47..16977.42 rows=100 width=40) (actual time=1.285..121.682 rows=100 loops=1) | |
| | 773 | Group Key: sh_1.stock_id | |
| | 774 | -> WindowAgg (cost=0.47..10472.42 rows=200000 width=28) (actual time=0.030..101.139 rows=200000 loops=1) | |
| | 775 | -> Index Only Scan using idx_sh_stock_timestamp on stock_history sh_1 (cost=0.42..6972.42 rows=200000 width=20) (actual time=0.018..30.274 rows=200000 loops=1) | |
| | 776 | Heap Fetches: 0 | |
| | 777 | -> Finalize GroupAggregate (cost=1000.44..7761.97 rows=1 width=40) (actual time=242.038..242.157 rows=1 loops=1) | |
| | 778 | Group Key: t.stock_id | |
| | 779 | -> Gather Merge (cost=1000.44..7761.93 rows=2 width=40) (actual time=241.940..242.069 rows=3 loops=1) | |
| | 780 | Workers Planned: 2 | |
| | 781 | Workers Launched: 2 | |
| | 782 | -> Partial GroupAggregate (cost=0.42..6761.68 rows=1 width=40) (actual time=147.936..147.937 rows=1 loops=3) | |
| | 783 | Group Key: t.stock_id | |
| | 784 | -> Parallel Index Only Scan using idx_txn_stock_timestamp on transactions t (cost=0.42..5355.42 rows=62500 width=24) (actual time=0.087..11.496 rows=50000 loops=3) | |
| | 785 | Heap Fetches: 0 | |
| | 786 | -> GroupAggregate (cost=10000002138.77..10000002288.97 rows=20 width=16) (actual time=13.241..18.369 rows=20 loops=1) | |
| | 787 | Group Key: w.stock_id | |
| | 788 | -> Sort (cost=10000002138.77..10000002188.77 rows=20000 width=16) (actual time=12.943..16.184 rows=20000 loops=1) | |
| | 789 | Sort Key: w.stock_id, w.user_id | |
| | 790 | Sort Method: external merge Disk: 512kB | |
| | 791 | -> Seq Scan on watchlist w (cost=10000000000.00..10000000367.00 rows=20000 width=16) (actual time=0.063..3.306 rows=20000 loops=1) | |
| | 792 | -> GroupAggregate (cost=10000000000.14..10000005477.72 rows=100 width=16) (actual time=2.399..47.769 rows=100 loops=1) | |
| | 793 | Group Key: s_1.id | |
| | 794 | -> Nested Loop (cost=10000000000.14..10000005459.00 rows=3544 width=16) (actual time=0.097..47.346 rows=3544 loops=1) | |
| | 795 | Join Filter: ((s_1.symbol)::text = (tr.stock_symbol)::text) | |
| | 796 | Rows Removed by Join Filter: 350856 | |
| | 797 | -> Index Scan using stock_pkey on stock s_1 (cost=0.14..14.64 rows=100 width=13) (actual time=0.019..0.281 rows=100 loops=1) | |
| | 798 | -> Materialize (cost=10000000000.00..10000000137.22 rows=3544 width=13) (actual time=0.001..0.190 rows=3544 loops=100) | |
| | 799 | -> Seq Scan on trade_request tr (cost=10000000000.00..10000000119.50 rows=3544 width=13) (actual time=0.056..1.147 rows=3544 loops=1) | |
| | 800 | Filter: ((status)::text = 'PENDING'::text) | |
| | 801 | Rows Removed by Filter: 1456 | |
| | 802 | Planning Time: 2.269 ms | |
| | 803 | JIT: | |
| | 804 | Functions: 73 | |
| | 805 | Options: Inlining true, Optimization true, Expressions true, Deforming true | |
| | 806 | Timing: Generation 8.438 ms (Deform 1.947 ms), Inlining 309.921 ms, Optimization 601.312 ms, Emission 504.049 ms, Total 1423.720 ms | |
| | 807 | Execution Time: 1654.111 ms | |
| | 808 | |
| | 809 | }}} |
| | 810 | |
| | 811 | idx_txn_stock_timestamp → Baseline: Seq Scan on transactions + Sort Method: external merge Disk: 5096kB. Со индексот: Parallel Index Only Scan using idx_txn_stock_timestamp + Heap Fetches: 0 + планерот активира parallel workers (2 workers). |
| | 812 | |
| | 813 | |
| | 814 | **3. idx_watchlist_stock_user ** |
| | 815 | {{{ |
| | 816 | CREATE INDEX idx_watchlist_stock_user |
| | 817 | ON watchlist (stock_id, user_id); |
| | 818 | |
| | 819 | EXPLAIN ANALYZE |
| | 820 | ... |
| | 821 | |
| | 822 | |
| | 823 | |
| | 824 | QUERY PLAN | |
| | 825 | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ |
| | 826 | Sort (cost=10000047955.10..10000047955.35 rows=100 width=338) (actual time=1601.286..1601.442 rows=100 loops=1) | |
| | 827 | Sort Key: (COALESCE((stddev((((sh.price - lag(sh.price) OVER (?)) / NULLIF(lag(sh.price) OVER (?), '0'::double precision)))) * '100'::double precision), '0'::double precision)) DESC | |
| | 828 | Sort Method: quicksort Memory: 46kB | |
| | 829 | -> WindowAgg (cost=10000047942.80..10000047951.78 rows=100 width=338) (actual time=1600.879..1601.347 rows=100 loops=1) | |
| | 830 | -> Sort (cost=10000047942.78..10000047943.03 rows=100 width=202) (actual time=1600.850..1601.007 rows=100 loops=1) | |
| | 831 | Sort Key: (COALESCE((COALESCE((stddev((((sh.price - lag(sh.price) OVER (?)) / NULLIF(lag(sh.price) OVER (?), '0'::double precision)))) * '100'::double precision), '0'::double precision)), '0'::double precision)) DESC| |
| | 832 | Sort Method: quicksort Memory: 39kB | |
| | 833 | -> WindowAgg (cost=10000047935.97..10000047939.46 rows=100 width=202) (actual time=1600.697..1600.935 rows=100 loops=1) | |
| | 834 | -> Sort (cost=10000047935.96..10000047936.21 rows=100 width=194) (actual time=1600.631..1600.788 rows=100 loops=1) | |
| | 835 | Sort Key: (((((COALESCE((count(DISTINCT w.user_id)), '0'::bigint))::numeric * 2.0) + (COALESCE((count(*)), '0'::bigint))::numeric) + ((COALESCE((count(tr.id)), '0'::bigint))::numeric * 3.0))) DESC | |
| | 836 | Sort Method: quicksort Memory: 38kB | |
| | 837 | -> Merge Left Join (cost=10000001001.96..10000047932.63 rows=100 width=194) (actual time=1244.977..1600.547 rows=100 loops=1) | |
| | 838 | Merge Cond: (s.id = s_1.id) | |
| | 839 | -> Merge Left Join (cost=1001.82..42450.66 rows=100 width=146) (actual time=1242.575..1552.403 rows=100 loops=1) | |
| | 840 | Merge Cond: (s.id = w.stock_id) | |
| | 841 | -> Merge Left Join (cost=1001.53..41733.47 rows=100 width=138) (actual time=1242.105..1546.828 rows=100 loops=1) | |
| | 842 | Merge Cond: (s.id = t.stock_id) | |
| | 843 | -> Merge Left Join (cost=1.09..33971.23 rows=100 width=106) (actual time=997.055..1301.564 rows=100 loops=1) | |
| | 844 | Merge Cond: (s.id = sh_1.stock_id) | |
| | 845 | -> Merge Left Join (cost=0.61..16991.31 rows=100 width=74) (actual time=995.695..1179.337 rows=100 loops=1) | |
| | 846 | Merge Cond: (s.id = sh.stock_id) | |
| | 847 | -> Index Scan using stock_pkey on stock s (cost=0.14..14.64 rows=100 width=34) (actual time=0.031..0.104 rows=100 loops=1) | |
| | 848 | -> GroupAggregate (cost=0.47..16974.17 rows=100 width=48) (actual time=2.087..185.453 rows=100 loops=1) | |
| | 849 | Group Key: sh.stock_id | |
| | 850 | -> WindowAgg (cost=0.47..11972.42 rows=200000 width=28) (actual time=0.163..157.533 rows=200000 loops=1) | |
| | 851 | -> Index Only Scan using idx_sh_stock_timestamp on stock_history sh (cost=0.42..6972.42 rows=200000 width=20) (actual time=0.114..43.186 rows=200000 loops=1) | |
| | 852 | Heap Fetches: 0 | |
| | 853 | -> GroupAggregate (cost=0.47..16977.42 rows=100 width=40) (actual time=1.330..122.037 rows=100 loops=1) | |
| | 854 | Group Key: sh_1.stock_id | |
| | 855 | -> WindowAgg (cost=0.47..10472.42 rows=200000 width=28) (actual time=0.035..100.974 rows=200000 loops=1) | |
| | 856 | -> Index Only Scan using idx_sh_stock_timestamp on stock_history sh_1 (cost=0.42..6972.42 rows=200000 width=20) (actual time=0.020..30.254 rows=200000 loops=1) | |
| | 857 | Heap Fetches: 0 | |
| | 858 | -> Finalize GroupAggregate (cost=1000.44..7761.97 rows=1 width=40) (actual time=244.996..245.137 rows=1 loops=1) | |
| | 859 | Group Key: t.stock_id | |
| | 860 | -> Gather Merge (cost=1000.44..7761.93 rows=2 width=40) (actual time=244.927..245.070 rows=3 loops=1) | |
| | 861 | Workers Planned: 2 | |
| | 862 | Workers Launched: 2 | |
| | 863 | -> Partial GroupAggregate (cost=0.42..6761.68 rows=1 width=40) (actual time=149.842..149.844 rows=1 loops=3) | |
| | 864 | Group Key: t.stock_id | |
| | 865 | -> Parallel Index Only Scan using idx_txn_stock_timestamp on transactions t (cost=0.42..5355.42 rows=62500 width=24) (actual time=0.108..11.561 rows=50000 loops=3) | |
| | 866 | Heap Fetches: 0 | |
| | 867 | -> GroupAggregate (cost=0.29..716.49 rows=20 width=16) (actual time=0.446..5.468 rows=20 loops=1) | |
| | 868 | Group Key: w.stock_id | |
| | 869 | -> Index Only Scan using idx_watchlist_stock_user on watchlist w (cost=0.29..616.29 rows=20000 width=16) (actual time=0.142..3.794 rows=20000 loops=1) | |
| | 870 | Heap Fetches: 0 | |
| | 871 | -> GroupAggregate (cost=10000000000.14..10000005477.72 rows=100 width=16) (actual time=2.370..47.843 rows=100 loops=1) | |
| | 872 | Group Key: s_1.id | |
| | 873 | -> Nested Loop (cost=10000000000.14..10000005459.00 rows=3544 width=16) (actual time=0.105..47.438 rows=3544 loops=1) | |
| | 874 | Join Filter: ((s_1.symbol)::text = (tr.stock_symbol)::text) | |
| | 875 | Rows Removed by Join Filter: 350856 | |
| | 876 | -> Index Scan using stock_pkey on stock s_1 (cost=0.14..14.64 rows=100 width=13) (actual time=0.028..0.264 rows=100 loops=1) | |
| | 877 | -> Materialize (cost=10000000000.00..10000000137.22 rows=3544 width=13) (actual time=0.001..0.191 rows=3544 loops=100) | |
| | 878 | -> Seq Scan on trade_request tr (cost=10000000000.00..10000000119.50 rows=3544 width=13) (actual time=0.053..1.160 rows=3544 loops=1) | |
| | 879 | Filter: ((status)::text = 'PENDING'::text) | |
| | 880 | Rows Removed by Filter: 1456 | |
| | 881 | Planning Time: 2.079 ms | |
| | 882 | JIT: | |
| | 883 | Functions: 69 | |
| | 884 | Options: Inlining true, Optimization true, Expressions true, Deforming true | |
| | 885 | Timing: Generation 9.372 ms (Deform 1.922 ms), Inlining 312.699 ms, Optimization 583.995 ms, Emission 491.538 ms, Total 1397.603 ms | |
| | 886 | Execution Time: 1609.894 ms | |
| | 887 | |
| | 888 | |
| | 889 | |
| | 890 | }}} |
| | 891 | |
| | 892 | idx_watchlist_stock_user → Baseline: Seq Scan on watchlist + Sort Method: external merge Disk: 512kB. Со индексот: Index Only Scan using idx_watchlist_stock_user + Heap Fetches: 0. |
| | 893 | |
| | 894 | |
| | 895 | **4. idx_tr_status_symbol ** |
| | 896 | {{{ |
| | 897 | CREATE INDEX idx_tr_status_symbol |
| | 898 | ON trade_request (status, stock_symbol) |
| | 899 | WHERE status = 'PENDING'; |
| | 900 | |
| | 901 | EXPLAIN ANALYZE |
| | 902 | ... |
| | 903 | |
| | 904 | QUERY PLAN | |
| | 905 | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ |
| | 906 | Sort (cost=42665.89..42666.14 rows=100 width=338) (actual time=419.467..419.632 rows=100 loops=1) | |
| | 907 | Sort Key: (COALESCE((stddev((((sh.price - lag(sh.price) OVER (?)) / NULLIF(lag(sh.price) OVER (?), '0'::double precision)))) * '100'::double precision), '0'::double precision)) DESC | |
| | 908 | Sort Method: quicksort Memory: 46kB | |
| | 909 | -> WindowAgg (cost=42653.59..42662.57 rows=100 width=338) (actual time=418.999..419.538 rows=100 loops=1) | |
| | 910 | -> Sort (cost=42653.57..42653.82 rows=100 width=202) (actual time=418.977..419.144 rows=100 loops=1) | |
| | 911 | Sort Key: (COALESCE((COALESCE((stddev((((sh.price - lag(sh.price) OVER (?)) / NULLIF(lag(sh.price) OVER (?), '0'::double precision)))) * '100'::double precision), '0'::double precision)), '0'::double precision)) DESC| |
| | 912 | Sort Method: quicksort Memory: 39kB | |
| | 913 | -> WindowAgg (cost=42646.77..42650.25 rows=100 width=202) (actual time=418.825..419.071 rows=100 loops=1) | |
| | 914 | -> Sort (cost=42646.75..42647.00 rows=100 width=194) (actual time=418.813..418.977 rows=100 loops=1) | |
| | 915 | Sort Key: (((((COALESCE((count(DISTINCT w.user_id)), '0'::bigint))::numeric * 2.0) + (COALESCE((count(*)), '0'::bigint))::numeric) + ((COALESCE(pst.pst_pending_count, '0'::bigint))::numeric * 3.0))) DESC | |
| | 916 | Sort Method: quicksort Memory: 38kB | |
| | 917 | -> Hash Left Join (cost=1192.56..42643.43 rows=100 width=194) (actual time=62.141..418.751 rows=100 loops=1) | |
| | 918 | Hash Cond: (s.id = pst.pst_stock_id) | |
| | 919 | -> Merge Left Join (cost=1001.82..42450.66 rows=100 width=146) (actual time=59.398..415.685 rows=100 loops=1) | |
| | 920 | Merge Cond: (s.id = w.stock_id) | |
| | 921 | -> Merge Left Join (cost=1001.53..41733.47 rows=100 width=138) (actual time=59.023..409.474 rows=100 loops=1) | |
| | 922 | Merge Cond: (s.id = t.stock_id) | |
| | 923 | -> Merge Left Join (cost=1.09..33971.23 rows=100 width=106) (actual time=3.629..353.874 rows=100 loops=1) | |
| | 924 | Merge Cond: (s.id = sh_1.stock_id) | |
| | 925 | -> Merge Left Join (cost=0.61..16991.31 rows=100 width=74) (actual time=2.155..211.070 rows=100 loops=1) | |
| | 926 | Merge Cond: (s.id = sh.stock_id) | |
| | 927 | -> Index Scan using stock_pkey on stock s (cost=0.14..14.64 rows=100 width=34) (actual time=0.031..0.224 rows=100 loops=1) | |
| | 928 | -> GroupAggregate (cost=0.47..16974.17 rows=100 width=48) (actual time=2.119..210.639 rows=100 loops=1) | |
| | 929 | Group Key: sh.stock_id | |
| | 930 | -> WindowAgg (cost=0.47..11972.42 rows=200000 width=28) (actual time=0.072..174.742 rows=200000 loops=1) | |
| | 931 | -> Index Only Scan using idx_sh_stock_timestamp on stock_history sh (cost=0.42..6972.42 rows=200000 width=20) (actual time=0.060..45.741 rows=200000 loops=1) | |
| | 932 | Heap Fetches: 0 | |
| | 933 | -> GroupAggregate (cost=0.47..16977.42 rows=100 width=40) (actual time=1.471..142.632 rows=100 loops=1) | |
| | 934 | Group Key: sh_1.stock_id | |
| | 935 | -> WindowAgg (cost=0.47..10472.42 rows=200000 width=28) (actual time=0.024..108.616 rows=200000 loops=1) | |
| | 936 | -> Index Only Scan using idx_sh_stock_timestamp on stock_history sh_1 (cost=0.42..6972.42 rows=200000 width=20) (actual time=0.021..30.572 rows=200000 loops=1) | |
| | 937 | Heap Fetches: 0 | |
| | 938 | -> Finalize GroupAggregate (cost=1000.44..7761.97 rows=1 width=40) (actual time=55.389..55.533 rows=1 loops=1) | |
| | 939 | Group Key: t.stock_id | |
| | 940 | -> Gather Merge (cost=1000.44..7761.93 rows=2 width=40) (actual time=55.378..55.522 rows=3 loops=1) | |
| | 941 | Workers Planned: 2 | |
| | 942 | Workers Launched: 2 | |
| | 943 | -> Partial GroupAggregate (cost=0.42..6761.68 rows=1 width=40) (actual time=25.926..25.927 rows=1 loops=3) | |
| | 944 | Group Key: t.stock_id | |
| | 945 | -> Parallel Index Only Scan using idx_txn_stock_timestamp on transactions t (cost=0.42..5355.42 rows=62500 width=24) (actual time=0.103..16.865 rows=50000 loops=3) | |
| | 946 | Heap Fetches: 0 | |
| | 947 | -> GroupAggregate (cost=0.29..716.49 rows=20 width=16) (actual time=0.369..6.122 rows=20 loops=1) | |
| | 948 | Group Key: w.stock_id | |
| | 949 | -> Index Only Scan using idx_watchlist_stock_user on watchlist w (cost=0.29..616.29 rows=20000 width=16) (actual time=0.086..3.968 rows=20000 loops=1) | |
| | 950 | Heap Fetches: 0 | |
| | 951 | -> Hash (cost=189.49..189.49 rows=100 width=16) (actual time=2.708..2.714 rows=100 loops=1) | |
| | 952 | Buckets: 1024 Batches: 1 Memory Usage: 13kB | |
| | 953 | -> Subquery Scan on pst (cost=187.49..189.49 rows=100 width=16) (actual time=2.657..2.692 rows=100 loops=1) | |
| | 954 | -> HashAggregate (cost=187.49..188.49 rows=100 width=16) (actual time=2.656..2.677 rows=100 loops=1) | |
| | 955 | Group Key: s_1.id | |
| | 956 | Batches: 1 Memory Usage: 24kB | |
| | 957 | -> Hash Join (cost=58.78..169.77 rows=3544 width=16) (actual time=0.277..1.953 rows=3544 loops=1) | |
| | 958 | Hash Cond: ((tr.stock_symbol)::text = (s_1.symbol)::text) | |
| | 959 | -> Bitmap Heap Scan on trade_request tr (cost=42.89..144.19 rows=3544 width=13) (actual time=0.180..0.788 rows=3544 loops=1) | |
| | 960 | Recheck Cond: ((status)::text = 'PENDING'::text) | |
| | 961 | Heap Blocks: exact=57 | |
| | 962 | -> Bitmap Index Scan on idx_tr_status_symbol (cost=0.00..42.00 rows=3544 width=0) (actual time=0.156..0.156 rows=3544 loops=1) | |
| | 963 | -> Hash (cost=14.64..14.64 rows=100 width=13) (actual time=0.074..0.075 rows=100 loops=1) | |
| | 964 | Buckets: 1024 Batches: 1 Memory Usage: 13kB | |
| | 965 | -> Index Scan using stock_pkey on stock s_1 (cost=0.14..14.64 rows=100 width=13) (actual time=0.016..0.051 rows=100 loops=1) | |
| | 966 | Planning Time: 2.119 ms | |
| | 967 | Execution Time: 419.999 ms | |
| | 968 | |
| | 969 | |
| | 970 | }}} |
| | 971 | |
| | 972 | idx_tr_status_symbol => Baseline: Seq Scan on trade_request + Filter: status = 'PENDING' + Rows Removed by Filter: 1456 + скапен Nested Loop Join Filter. Со индексот: Bitmap Index Scan on idx_tr_status_symbol => Bitmap Heap Scan + Hash Join наместо Nested Loop. Ова е најголемото забрзување — 4.8x. |