Lagi

Pemrosesan Hasil ST_ValueCount yang efisien di Postgresql

Pemrosesan Hasil ST_ValueCount yang efisien di Postgresql


Masalah Umum: Saya memiliki tabel raster. Raster diklasifikasikan sebagai gambar MSI, sehingga setiap piksel adalah bilangan bulat yang menunjukkan kelas piksel. Untuk sejumlah wilayah, saya menanyakan jumlah piksel di wilayah tersebut, yaitu membuat tabel seperti:

nama file | jumlah piksel total | piksel di kelas 0 | piksel di kelas 1 |…

Masalah Khusus: Masalah saya adalah skrip membutuhkan waktu lama, jadi saya ingin menurunkan runtime.

Yang sudah saya coba: Pengungkapan penuh, saya tidak berpengalaman dalam postgresql. Juga, perhatikan bahwa dalam dua cuplikan kode di bawah ini, sub-pilihan paling dalam adalah identik. Inilah upaya pertama saya:

JELASKAN ANALISIS PILIH nama file SEBAGAI nama file, ST_Count(rast,1) AS totalpiksel, (ST_ValueCount(rast,1,false,ARRAY[0.0])).count AS nodata, (ST_ValueCount(rast,1,false,ARRAY[1.0]) ).hitung AS sayuran rendah, (ST_ValueCount(rast,1,false,ARRAY[2.0])).count AS highveg, (ST_ValueCount(rast,1,false,ARRAY[12.0])).count AS awan, (ST_ValueCount(rast ,1,false,ARRAY[13.0])).hitung SEBAGAI bayangan FROM ( SELECT nama file, ST_Clip(rast,ST_GeomFromText('POLYGON ((125.229490000007 6.900509999999138, 125.2404900000019 6.900509999999138)) 125.2404900000019 6.889510000009004179, 125.88999 ) SEBAGAI rast DARI raster WHERE ST_Intersects(rast,ST_GeomFromText('POLYGON ((125.229490000007 6.900509999999138, 125.2404900000019 6.900509999999138, 125.2404900000019 6.889510000004179, 125.229490000007 6.889510000004179, ) 9005099999943)

Ini berjalan dalam 185 ms. Saya pikir pasti itu kurang optimal untukST_ValueCountBerkali-kali. Jadi, inilah upaya saya yang ditingkatkan -- menjalankannya sekali dan mengonversi hasil SETOF ke array sehingga saya dapat mengindeks nilainya:

JELASKAN ANALISIS SELECT nama file SEBAGAI nama file, totalpiksel AS total piksel, pxcnt[1] AS nodata, pxcnt[2] AS lowveg, pxcnt[3] AS highveg, pxcnt[4] AS cloud, pxcnt[5] AS shadow FROM ( SELECT nama file AS nama file, ST_Count(rast,1,false) AS totalpiksel, ARRAY( SELECT count FROM ST_ValueCount(rast,1,false,ARRAY[0.0,1.0,2.0,12.0,13.0]) ) AS pxcnt FROM ( SELECT filename, ST_Clip(rast , ST_GeomFromText ( 'Polygon ((125,229490000007 6,900509999999138, 125,2404900000019 6,900509999999138, 125,2404900000019 6,889510000004179, 125,229490000007 6,889510000004179, 125,229490000007 6,900509999999138))', 4326)) AS rast DARI raster MANA ST_Intersects (rast, ST_GeomFromText ( 'Polygon ((125,229490000007 6,900509999999138, 125,2404900000019 6,900509999999138, 125,2404900000019 6.889510000004179, 125.229490000007 6.889510000004179, 125.229490000007 6.900509999999138))',4326)) ) AS source_rasters ) AS f;

Tapi itu hanya mengurangi runtime menjadi 155 ms.

Tapi kemudian saya berpikir mungkin ST_ValueCount hanya sebagian kecil dari total biaya pekerjaan, jadi ini semua peningkatan yang bisa saya harapkan. Namun, jika saya merujuk hanya satu hasil:

JELASKAN ANALISIS PILIH nama file SEBAGAI nama file, totalpiksel SEBAGAI totalpiksel, pxcnt[1] SEBAGAI nodata DARI…

Ini memotong runtime menjadi 55 ms, yang saya tidak mengerti karena tampaknya telah melakukan semua pekerjaan berpotongan, memotong, menghitung, dll.

Pertanyaan: Jadi apakah ada cara yang lebih cepat untuk membongkar hasil ST_ValueCount, atau cara yang jelas untuk mempercepat ini secara umum?

Hanya untuk apa nilainya, saya telah membuat peningkatan tambahan lainnya sejak saya mulai, misalnya, memasang raster adalah peningkatan besar. Pada titik ini, ini sepertinya peluang yang paling mungkin untuk peningkatan yang signifikan, beri tahu saya jika saya salah tentang itu.


Tonton videonya: PostgreSQL In-Depth Training: Fundamentals Part 1