13 Kasım 2023 Pazartesi

NESTED LOOP Scan

Giriş
Scan çeşitleri tek bir tablo varsa kullanılır. Eğer bir işlemde - örneğin JOIN - iki tane tablo varsa dışarıda bir NESTED LOOP içeride de Scan çeşitlerinden birkaç tanesi kullanılır

Örnek
Elimizde şöyle bir SQL olsun. Burada customer_id = 5 olan müşterini siparişleri sayılıyor
EXPLAIN ANALYZE SELECT count(*)
FROM orders AS o
 JOIN order_items as oi
  ON o.order_id = oi.order_item_order_id
WHERE o.order_customer_id = 5;
Çıktısı şöyle. Burada dışarıdaki döngü için Bitmap Index Scan ve Bitmap Heap Scan kullanılıyor. İçerideki döngü için Index Only Scan kullanılıyor
|QUERY PLAN                                                                                                                                                         |
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|Aggregate  (cost=53.71..53.72 rows=1 width=8) (actual time=2.434..2.435 rows=1 loops=1)                                                                            |
|  ->  Nested Loop  (cost=4.76..53.67 rows=15 width=0) (actual time=1.872..2.428 rows=7 loops=1)                                                                    |
|        ->  Bitmap Heap Scan on orders o  (cost=4.34..26.49 rows=6 width=4) (actual time=1.034..1.315 rows=4 loops=1)                                              |
|              Recheck Cond: (order_customer_id = 5)                                                                                                                |
|              Heap Blocks: exact=4                                                                                                                                 |
|              ->  Bitmap Index Scan on orders_order_customer_id_idx  (cost=0.00..4.34 rows=6 width=0) (actual time=0.696..0.696 rows=4 loops=1)                    |
|                    Index Cond: (order_customer_id = 5)                                                                                                            |
|        ->  Index Only Scan using order_items_order_item_order_id_idx on order_items oi  (cost=0.42..4.49 rows=4 width=4) (actual time=0.275..0.276 rows=2 loops=4)|
|              Index Cond: (order_item_order_id = o.order_id)                                                                                                       |
|              Heap Fetches: 0                                                                                                                                      |
|Planning Time: 5.706 ms                                                                                                                                            |
|Execution Time: 2.565 ms      
Örnek - GroupAggregate  
GROUP BY varsa kullanılır Elimizde şöyle bir SQL olsun. Siparişleri gruplar ve toplam ciroyu verir.
EXPLAIN SELECT o.*, round(sum(oi.order_item_subtotal)::numeric, 2) as revenue FROM orders as o JOIN order_items as oi ON o.order_id = oi.order_item_order_id WHERE o.order_id = 2 GROUP BY o.order_id, o.order_date, o.order_customer_id, o.order_status;
Çıktı şöyle
|order_id|order_date |order_customer_id|order_status |revenue| |--------|-----------------------|-----------------|---------------|-------| |2 |2013-07-25 00:00:00.000|256 |PENDING_PAYMENT|579.98 |
Plan şöyle. Bu sefer Nested Loop dışında bir tane de GroupAggregate var
|QUERY PLAN                                                                             |
|---------------------------------------------------------------------------------------|
|GroupAggregate  (cost=0.29..3427.86 rows=1 width=58)                                   |
|  Group Key: o.order_id                                                                |
|  ->  Nested Loop  (cost=0.29..3427.82 rows=4 width=34)                                |
|        ->  Index Scan using orders_pkey on orders o  (cost=0.29..8.31 rows=1 width=26)|
|              Index Cond: (order_id = 2)                                               |
|        ->  Seq Scan on order_items oi  (cost=0.00..3419.47 rows=4 width=12)           |
|              Filter: (order_item_order_id = 2)            




Hiç yorum yok:

Yorum Gönder