EXPLAIN ANALYZE etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
EXPLAIN ANALYZE etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

8 Eylül 2023 Cuma

Sequential Scan

Giriş
Not : Parallel Sequential Scan aynı Sequential Scan gibidir, sadece birden fazla worker kullanılır.

Açıklaması şöyleFull Table Scan olarak da bilinir. Tabloda index yoksa mecburen Full Table Scan yapılır. 
This is the simplest of them all; if there is no index or a lesser number of rows, then the Planner resorts to scanning all of the rows present. You would/should never encounter Sequential Scans in a typical production system since they are very slow and get slower as the data increases. There are exceptions when the table is too small where an index is pointless and Sequential Scans are fast enough that you don’t have to worry.
Açıklaması şöyle
One thing to understand is that there are certain kinds of queries, such as Count, Avg and other aggregate queries, which always result in Sequential Scan because they have to scan the entirety of the table anyway for the result. 
Örnek
Şöyle yaparız. Burada Seq Scan metninden de görüldüğü gibi sequential scan kullanılıyor
explain analyze SELECT EXISTS (
  SELECT
    1
  FROM
    balances_snapshots
  WHERE
    total_balance = double precision 'NaN'
  LIMIT 1
) as exists;
                                                                QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------
 Result  (cost=4.75..4.76 rows=1 width=1) (actual time=237365.680..237365.681 rows=1 loops=1)
   InitPlan 1 (returns $0)
     ->  Seq Scan on balances_snapshots  (cost=0.00..9257326.32 rows=1948181 width=0) (actual time=237365.675..237365.676 rows=0 loops=1)
           Filter: ((total_balance)::double precision = 'NaN'::double precision)
           Rows Removed by Filter: 389636289
 Planning Time: 23.985 ms
 Execution Time: 237365.719 ms
(7 rows)
Sebebi ise total_balance alanının "numeric" olması. Ancak sorguda "double precision" yani double olarak arama yapılıyor

Örnek
Şöyle yaparız. Burada event_type için indeks yok
EXPLAIN ANALYZE SELECT * FROM weather WHERE event_type = 'Winter Storm'; 

Seq Scan on weather (cost=0.00..115.00 rows=11] width=622) (actual time=0.100..19.800 rows=11] loops=1)
  Filter: ((event type)::text = 'Winter Storm'::text)
  Rows Removed by Filter: 1189
Planning Time: 30.000 ms
Execution Time: 20.800 ms
(5 rows)
Bir indeks yaratırsak Sequential Scan yapmaz
CREATE INDEX idx weather_type ON weather(event_type); 
Eğer where koşulunda iki tane sütun olsaydı indekste iki tane alan olmalıydı ve alanların sırası önemli. Şöyle yaparız 
CREATE INDEX idx_storm_crop ON weather (event_type, damage_crops); 
SELECT * FROM weather WHERE event_type = 'Winter Storm' AND damage_crops > 0;        
Eğer GROUP BY kullanırsak yine Sequential Scans yapar 
SELECT state FROM weather 
WHERE event_type = 'Winter Storm’ AND damage_crops > O
GROUP BY state; 
Açıklaması şöyle
The planner will need to load all of the data to the memory and sort all of the data by state, then for each state it’ll need to filter out by our WHERE statement.
Bu sefer indeki büyütmek gerekiyor. Şöyle yaparız 
CREATE INDEX idx_storm_crop ON weather (state, event_type, damage_crops);


28 Ekim 2021 Perşembe

EXPLAIN ANALYZE - Cümleyi Çalıştırır

Giriş
SQL cümlesi için kullanılan "Query Plan" bilgisini gösterir. Açıklaması şöyle
There are several node types in PostgreSQL query plans,
Scans.
Joins.
Sort.
Aggregates etc.,
Explain vs Explain Analyze
Explain için söz dizimi şöyle
EXPLAIN (ANALYZE, VERBOSE) SELECT * FROM your_table WHERE condition;
Açıklaması şöyle. Yani EXPLAIN ANALYZE cümleyi çalıştırır
You can use the EXPLAIN and EXPLAIN ANALYZE commands to view the query plan and see if it makes sense (i.e. by running EXPLAIN ANALYZE <query_statement>).

Note that EXPLAIN is a read-only DB operation but EXPLAIN ANALYZE isn’t! Be very careful not to use EXPLAIN ANALYZE on an UPDATE or DELETE statement, as it will actually execute the query and modify the database.

Scan Çeşitleri
Bazı çeşitler şöyle
1. Sequential Scans
2. Index Scans
3. Index Only Scans
4. Bitmap Heap Scan & Bitmap Index Scan
5. Parallel Scans

1. Sequential Scans
Sequential Scans yazısına taşıdım

2. Index Scans
Eğer tabloda bir sütun için indeks varsa kullanılır. Index genellikle where koşulundaki sütuna konulur

Where koşulu Sırası
Açıklaması şöyle. Yani (tenantId, status) şeklinde index olsa bile ikinci sırada belirtilen where koşulu bunu kullanmayabiliyor. (status, tenantId) şeklinde yeni bir index yaratılabilir ama bence en kolayı sorguyu değiştirmek
Two of the queries had the following WHERE clause:
WHERE "tenantId" = 'some_tenant_id' AND "status" != 'dismissed'.
The other two had the conditions in the opposite order:
WHERE "status" != 'dismissed' AND "tenantId" = 'some_tenant_id'.

Postgres may choose different execution plans depending on the order of the conditions in the WHERE clause, so it treated these as distinct queries. As mentioned earlier, I added a multi-column index on the (tenantId, status) columns in the Notes table, but this only improved the performance of the first two queries. The other two queries, which had the opposite order of conditions in the WHERE clause, were unable to benefit from this index.

Örnek
Şöyle yaparız. Burada id alanı için indeks yaratılıyor
CREATE INDEX id_idx ON fake_data USING BTREE(id);
Sorgu için şöyle yaparız
EXPLAIN ANALYZE SELECT * FROM fake_data WHERE 
 fake_data.id = 1000;
Örnek
Şöyle yaparız
SELECT * FROM songs WHERE (artists_id = 1 AND album_id = 1);
Çıktısı şöyle
Index Scan using songs_artists_id_album_id_index on songs  
(cost=0.28..6.05 rows=1 width=159) (actual time=5.555..5.562 rows=10 loops=1)
   Index Cond: ((artists_id = 1) AND (album_id = 1))
 Planning Time: 311.482 ms
 Execution Time: 9.266 ms
(4 rows)
Açıklaması şöylee
(cost=0.28..6.05 rows=1 width=159) refers to the planner's estimations while (actual time=5.555..5.562 rows=10 loops=1) refers to the actual results of the executing the plan. The planner estimated 1 row would be returned, but there were actually 10.

The planner calculated its row estimate by first taking the total number of Songs (1000), then considering the artists_id filter. 10% of Songs have artists_id = 1 so that leaves 100 Songs. Next it considers the album_id filter. 1% of Songs have album_id = 1, so it's left with 1 Song.

The key piece of information Postgres is missing is that artist_id and album_id are strongly correlated. In fact, knowing the album_iduniquely determines the artist_id. Had Postgres known about this, it could have used only the album_id = 1 filter in its estimation and come up with the correct result of 10 Songs.

3. Index Only Scans
Index Only Scans yazısına taşıdım

4. Bitmap Index Scan ve Bitmap Heap Scan