Mengoptimalkan Geometri.STIntersect Query

8

Saya mencoba untuk memindahkan rutin Geoprocessing sederhana dari proses berbasis ESRI ke SQL Server. Asumsi saya adalah bahwa itu akan jauh lebih efisien. Untuk pengujian awal saya, saya mengerjakan rutin persimpangan untuk mengasosiasikan data linier yang tumpang tindih.

Dalam tabel WCASING saya, saya memiliki 1610 catatan. Saya mencoba mengaitkan Casing ini dengan induknya yang terkait. Saya memiliki ~ 277.000 Listrik. Saya memiliki ~ 1.600 Selubung.

Saya menjalankan kueri di bawah ini untuk mendapatkan gambaran umum tentang berapa lama waktu yang dibutuhkan untuk menemukan kecocokan individu. Kueri ini mengembalikan 5 persimpangan yang valid dalam 40 detik.

SELECT Top 5 [WCASING].[OBJECTID] As CasingOBJECTID, 
    [WPUMPPRESSUREMAIN].[OBJECTID] AS MainObjectID, [WCASING].[Shape]
FROM [dbo].[WPUMPPRESSUREMAIN]
    JOIN [WCASING] 
        ON [WCASING].[Shape].STIntersects([WPUMPPRESSUREMAIN].[Shape]) = 1

Pertanyaan Utama saya;

Apakah proses ini lebih cepat tergantung pada urutan pencarian?

  • Menemukan 'A' di dalam 'B' vs
  • Menemukan 'B' di dalam 'A'
  • Pengembalian awal pada 5 catatan dari dataset ini adalah bahwa itu tidak masalah

Akankah proses ini lebih cepat, jika saya buffer dulu membatasi ke set utama yang lebih kecil dan kemudian mencari?

Bisakah saya menggunakan SQL Server Tuning untuk bekerja dengan kueri berbasis Geometri?

SELECT WCASING.OBJECTID AS CasingOBJECTID,
    WPUMPPRESSUREMAIN.OBJECTID AS MainObjectID, WCASING.UFID AS UFID,
    WPUMPPRESSUREMAIN_IPS.UFID AS MainUFID, WCASING.SHAPE
INTO WCASING_INTDefsV6
FROM WCASING with (index([FDO_ShapeWC])) 
    INNER JOIN [WPUMPPRESSUREMAIN_IPS] ON 
        [WPUMPPRESSUREMAIN_IPS].Shape.STIntersects(WCASING.SHAPE) = 1

Permintaan baru ini telah meningkatkan definisi.

  • Sekarang kedua tabel memiliki indeks spasial
  • Sebelumnya Casing Table (Lebih Kecil) tidak memiliki Indeks Spasial
    • Itu memang mengandung Indeks Non-Clustered

Permintaan juga memiliki pernyataan dengan indeks.

Permintaan baru butuh 37 menit. Permintaan lama butuh 44 menit.

Saya berharap untuk hasil yang lebih baik dan akan terus menguji.

Rick Monteiro
sumber
1
menyenangkan, bukan !?
DPSSpatial
Itu mengagumkan. Saya telah berada di posisi baru selama satu tahun, bekerja dengan dataset yang sangat besar dan kurva pembelajaran dengan SQL Server telah menjadi bagian yang paling menyenangkan. Saya masih noob dalam banyak hal, tetapi saya telah belajar beberapa hal keren.
Rick Monteiro
1
Kami telah menggunakan data spasial SQL Server dan fungsi untuk analisis kami selama hampir 2 tahun dan kami tidak akan kembali dalam waktu dekat !!!
DPSSpatial
Saya berharap memaksa indeks pada tabel yang lebih besar (listrik) akan memiliki kinerja yang lebih baik.
MickyT

Jawaban:

7

Saya berasumsi bahwa Anda menggunakan Geometri, tetapi metodologi umumnya tetap sama.

Saat menyetel kueri spasial, ini adalah langkah yang saya ambil

  1. Ini adalah langkah terpenting . Periksa indeks yang sesuai untuk tabel. Jika Anda memiliki SQL Server 2012+ maka saya akan menyarankan Anda menggunakan AUTO GRID. Ini memberi Anda kotak yang lebih halus. Pastikan luasan mencakup data dan jangan sampai jauh dari itu. Jika mengindeks poligon atau garis maka coba dan tentukan nilai Cells Per Object yang masuk akal. The gambaran pengindeksan spasial cukup baik menjelaskan hal itu.

  2. Tulis kueri dalam bentuk yang paling sederhana terlebih dahulu. Periksa Perkiraan Rencana Eksekusi untuk memastikan bahwa indeks spasial yang Anda harapkan sedang digunakan. Jalankan kueri dan dapatkan timing dan statistik IO. Rencana pelaksanaan yang sebenarnya juga akan sangat membantu. Ini akan menjadi garis dasar Anda.

  3. Coba variasi kueri, termasuk menukar urutan geometri dalam perbandingan geometri, dll. Kumpulkan statistik untuk masing-masing.

  4. Coba pecahkan kueri di bagian yang lebih kecil jika memungkinkan (bagi dan taklukkan). Terkadang ini menghasilkan eksekusi yang lebih cepat secara keseluruhan.

  5. Jika semuanya gagal dan Anda tidak bisa mendapatkan kueri untuk menggunakan indeks spasial, gunakan petunjuk indeks. Ini adalah upaya terakhir dan berpotensi berarti mungkin ada masalah dengan pengindeksan di atas meja. Yang mengatakan optimizer tidak selalu benar.

Lihatlah rencana eksekusi dan habiskan sedikit waktu untuk mencoba memahaminya. Mereka benar-benar temanmu. Ada juga alat di luar sana yang membuatnya lebih mudah untuk ditafsirkan. Yang saya gunakan adalah SQL Sentry .

Adapun kueri yang Anda posting, saya pikir itu akan menjadi pemain terbaik, tetapi di sini ada variasi yang ingin Anda coba. Juga operator TOP akan mempengaruhi cara rencana eksekusi dibangun, jadi itu berarti Anda mungkin tidak akan mendapatkan perbandingan yang baik antara metode yang berbeda.

SELECT c.[OBJECTID] As CasingOBJECTID, 
    x.[OBJECTID] AS MainObjectID, 
    c.[Shape]
FROM [WCASING] c -- Smallest Table
    CROSS APPLY (
        -- This query is essentially done for each casing
        SELECT p.[OBJECTID]
        FROM [dbo].[WPUMPPRESSUREMAIN] p -- Largest table
        WHERE p.[Shape].STIntersects(c.[Shape]) = 1 -- should use the pressure main spatial index
        ) x
MickyT
sumber
1

Apa yang saya temukan mempercepat pertanyaan persimpangan ini adalah memaksa indeks spasial:

Dalam pandangan yang saya berikan ke BI yang memotong ~ 280.000 titik alamat dengan ~ 300 poligon batas, saya memaksakan penggunaan indeks spasial titik alamat:

...

FROM [dpsdata].[Address_Master] as am with (index(SIndx_AddrMsterIC))
  left outer join [dpsdata].[SchoolBoundaries_All_Projected] as sbp
  on (am.shape.STIntersects(sbp.shape) =1)

(Dengan asumsi kedua tabel memiliki indeks spasial sudah dibangun tentu saja ...)

Ini membutuhkan waktu hampir 1 menit untuk berlari, turun dari beberapa menit.

Dalam kasus Anda, sesuatu seperti ini seharusnya berfungsi:

SELECT Top 5 [WCASING].[OBJECTID] As CasingOBJECTID, 
    [WPUMPPRESSUREMAIN].[OBJECTID] AS MainObjectID, [WCASING].[Shape]
FROM [dbo].[WPUMPPRESSUREMAIN] with (index(PK__WPUMPPRE__E458E6E7F06C9A87)) 
    JOIN [WCASING] 
        ON [WCASING].[Shape].STIntersects([WPUMPPRESSUREMAIN].[Shape]) = 1
DPSSpatial
sumber
Saya mencoba ini. Itu tidak berfungsi seperti yang saya coba implementasikan. "SELECT Top 5 WCASING.OBJECTID AS CasingOBJECTID, WPUMPPRESSUREMAIN.OBJECTID_1 AS MainObjectID, WCASING.UFID, WCASING.SHAPE dengan (indeks (PK__WPUMPPRE__E458E6E7F06C9A87)) KE WCASING_INTDefs_V2 DARI WCASING INNER JOIN WPUMPPRESSUREMAIN ON WPUMPPRESSUREMAIN.Shape.STIntersects (WCASING.SHAPE) = 1 "mengembalikan kesalahan. "Msg 319, Level 15, Negara 1, Baris 1 Sintaks salah di dekat kata kunci 'with'. Jika pernyataan ini adalah ekspresi tabel yang umum, ..."
Rick Monteiro
Saya belum pernah menggunakan opsi 'with' sebelumnya. Apakah ini khusus untuk bidang atau pernyataan Dari pada umumnya. Bisakah saya memiliki dua pernyataan 'dengan' satu untuk setiap tabel? Pertanyaan kedua, haruskah indeks menjadi indeks spasial?
Rick Monteiro
1a) 'with' digunakan dalam kasus ini dalam pernyataan FROM dan 1b) Saya tidak tahu apakah ini akan berfungsi jika Anda menggunakan 2 'dengan' pernyataan ... 2) Saya hanya mencoba ini dengan indeks spasial
DPSSpatial
1
Saya memperbarui jawaban saya untuk menunjukkan bagaimana Anda dapat menggunakan indeks spasial Anda dalam kueri dalam posting asli Anda ...
DPSSpatial
1
@RichardMonteiro maaf saya lupa 'dengan' sebelum indeks spasial dalam jawaban saya menggunakan contoh Anda ... Saya telah memperbarui.
DPSSpatial