PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Meneliti kelambatan PostGIS (edisi 2019)

Sama seperti tahun lalu yang berakhir, salah satu pelanggan lama kami datang kepada kami karena salah satu kueri PostgreSQL mereka yang sudah lama melibatkan perhitungan geometri PostGIS jauh lebih lambat untuk nilai tertentu. Kami meneliti masalah dan menemukan cara untuk menyelesaikannya; baca terus! Apa yang kami temukan sebagai penyebab masalah akan mengejutkan Anda!

Pengamatan awal, yang dilaporkan oleh pelanggan kami, adalah menjalankan kueri yang melibatkan ST_DistanceSpheroid membutuhkan waktu sekitar 7 milidetik saat diminta untuk mengembalikan jarak ke POINT(33.681953 23.155994) pada spheroid tertentu, tetapi jika titik tersebut dipindahkan ke POINT(33.681953 23.1559941) (perbedaan hanya 0.0000001 ) maka butuh 0,13 milidetik. 60 kali lebih cepat! Apa yang mungkin terjadi di Bumi (bola lain!)?

Awalnya, kami tidak dapat mereproduksi kelambatan di lingkungan pengujian kami. Di tangan kami, kedua kueri akan berkinerja sama cepatnya, tanpa pelambatan. Kami menggali ke versi perangkat lunak tertentu yang digunakan dengan pemikiran bahwa pembaruan mungkin diperlukan. Kami menggunakan versi yang dilaporkan oleh pelanggan:PostgreSQL 10.11, PostGIS 2.4.4, libproj 4.93. Kami kembali ke zaman gua dengan menurunkan versi ke versi yang tepat, tanpa hasil.

Akhirnya kami menyadari bahwa pelanggan menggunakan Ubuntu 18.04, jadi kami mencobanya ... dan lihatlah, masalahnya mereproduksi di sana. Cukuplah untuk mengatakan bahwa kami mengambil kesempatan untuk membuat profil kueri di mesin itu. Kami mendapatkan ini:

Samples: 224K of event 'cpu-clock', Event count (approx.): 56043500000
  Children      Self  Command   Shared Object           Symbol
+   84.86%     0.00%  postgres  [unknown]               [.] 0xffffffffffffffff
+   84.59%     0.00%  postgres  postgres                [.] DirectFunctionCall4Coll
+   84.58%     0.00%  postgres  postgis-2.5.so          [.] geometry_distance_spheroid
+   84.56%     0.00%  postgres  liblwgeom-2.5.so.0.0.0  [.] lwgeom_distance_spheroid
+   84.31%     0.19%  postgres  libm-2.27.so            [.] __sincos
+   84.18%     0.00%  postgres  libm-2.27.so            [.] __cos_local (inlined)
+   84.13%     0.00%  postgres  libm-2.27.so            [.] cslow2 (inlined)
+   84.05%     0.01%  postgres  libm-2.27.so            [.] __mpcos
+   83.95%     0.32%  postgres  libm-2.27.so            [.] __c32
+   83.87%     0.00%  postgres  postgres                [.] ExecInterpExpr
+   83.75%     0.00%  postgres  postgres                [.] standard_ExecutorRun
+   83.75%     0.00%  postgres  postgres                [.] ExecutePlan (inlined)
+   83.73%     0.00%  postgres  postgres                [.] ExecProcNode (inlined)
+   83.73%     0.00%  postgres  postgres                [.] ExecScan
+   83.67%     0.00%  postgres  postgres                [.] ExecProject (inlined)
+   83.67%     0.00%  postgres  postgres                [.] ExecEvalExprSwitchContext (inlined)
+   83.65%     0.00%  postgres  postgres                [.] _SPI_execute_plan
+   83.60%     0.00%  postgres  postgres                [.] _SPI_pquery (inlined)
+   83.49%     0.01%  postgres  plpgsql.so              [.] exec_stmts
+   83.49%     0.00%  postgres  plpgsql.so              [.] exec_stmt (inlined)
+   83.49%     0.00%  postgres  plpgsql.so              [.] exec_stmt_fori (inlined)
+   83.48%     0.00%  postgres  plpgsql.so              [.] exec_stmt_perform (inlined)
+   83.48%     0.00%  postgres  plpgsql.so              [.] exec_run_select
+   83.47%     0.00%  postgres  postgres                [.] SPI_execute_plan_with_paramlist
+   81.67%     0.01%  postgres  liblwgeom-2.5.so.0.0.0  [.] edge_distance_to_point
+   81.67%     0.00%  postgres  liblwgeom-2.5.so.0.0.0  [.] 0x00007f2ce1c2c0e6
+   61.85%    60.82%  postgres  libm-2.27.so            [.] __mul
+   54.83%     0.01%  postgres  liblwgeom-2.5.so.0.0.0  [.] sphere_distance
+   27.14%     0.00%  postgres  plpgsql.so              [.] exec_stmt_block
+   26.67%     0.01%  postgres  liblwgeom-2.5.so.0.0.0  [.] geog2cart
+   19.24%     0.00%  postgres  libm-2.27.so            [.] ss32 (inlined)
+   18.28%     0.00%  postgres  libm-2.27.so            [.] cc32 (inlined)
+   12.55%     0.76%  postgres  libm-2.27.so            [.] __sub
+   11.46%    11.40%  postgres  libm-2.27.so            [.] sub_magnitudes
+    8.15%     4.89%  postgres  libm-2.27.so            [.] __add
+    4.94%     0.00%  postgres  libm-2.27.so            [.] add_magnitudes (inlined)
+    3.18%     3.16%  postgres  libm-2.27.so            [.] __acr
+    2.66%     0.00%  postgres  libm-2.27.so            [.] mcr (inlined)
+    1.44%     0.00%  postgres  liblwgeom-2.5.so.0.0.0  [.] lwgeom_calculate_gbox_geodetic
+    1.44%     0.00%  postgres  liblwgeom-2.5.so.0.0.0  [.] ptarray_calculate_gbox_geodetic

Omong kosong, katamu. Namun, ada sesuatu yang sangat ingin tahu tentang profil ini … dan Anda harus mengabaikan 26 baris pertama dan fokus pada __mul garis di sana. Lihat 60,82% dari waktu "diri sendiri" itu? (Saya dapat mendengar suara kesadaran yang baru saja dibuat oleh pikiran Anda). Jadi mengapa butuh begitu banyak waktu untuk titik-titik tertentu pada spheroid dan bukan yang lain? Dan juga mengapa butuh waktu lama di Ubuntu 18.04 tetapi tidak di mesin lain? Mengapa memutakhirkan PostGIS tidak menyelesaikan masalah?

Jawabannya disarankan kepada saya setelah saya menyadari apa yang jelas:PostGIS melakukan banyak trigonometri (sinus, kosinus, tangen dll) dengan memanggil libm fungsi. Melihat log perubahan glibc, kami menemukan beberapa pengoptimalan dalam fungsi trigonometri:untuk input tertentu, perhitungan trigonometri mengambil jalan pintas yang tidak dapat diambil untuk input lain; dan pintasan semacam itu telah dioptimalkan dari waktu ke waktu. Memang, glibc mengumumkan untuk 2.27 dan 2.29 keduanya menyebutkan pengoptimalan dalam fungsi sinus/cosinus/dll. Rupanya, pernah ada beberapa pengoptimalan oleh Intel yang seharusnya memberikan hasil yang sangat akurat, tetapi kemudian seseorang menyadari bahwa klaim akurasi itu salah, jadi glibc menonaktifkan penggunaan pengoptimalan tersebut; kemudian, hal itu diterapkan kembali dengan cara yang berbeda tetapi sekali lagi dengan cepat. Atau sesuatu seperti itu — untuk orang luar seperti saya, sulit untuk mengetahui detail pastinya.

Kami menduga bahwa memutakhirkan ke versi glibc yang lebih baru akan memperbaiki masalah, membiarkan yang lainnya tetap sama. Pelanggan kami mencobanya, dan memang benar, dan mereka senang. Kami tidak begitu yakin yang mana dari perubahan glibc ini bertanggung jawab, tetapi satu hal yang jelas:selalu merupakan ide yang baik untuk menjalankan berbagai hal pada perangkat lunak terbaru.

Ingatlah bahwa tepi yang berdarah itu tajam ... jadi berhati-hatilah di luar sana.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Replikasi Streaming PostgreSQL - Penyelaman Mendalam

  2. `pg_tblspc` hilang setelah penginstalan versi terbaru OS X (Yosemite atau El Capitan)

  3. Hitung jumlah acara bersamaan dalam SQL

  4. Nilai kesalahan tidak ada - masalah postgresql INSERT INTO

  5. Mengonfigurasi PostgreSQL untuk Kelangsungan Bisnis