PostgreSQL / PostGIS uzamsal endeksi - hızlanma yok


15

PostgreSQL / PostGIS veritabanında uzamsal bir tablo var. İçindeki her satır bir Çokgeni temsil eder. Aşağıdaki biçimdedir:

+----+--------+
|gid |   way  |
+----+--------+
|241 | 01030..|

Geometrik sütun, bir çokgenin geometrisini içeren "yoldur". WKT'de: POLYGON (('....')). İki çokgen birbirine örneğin olup olmadığını test etmek için bu tablodaki ST_Contains sorguları bir sürü yapıyorum:

Select ST_Contains(a.way, b.way) From table AS a, table AS b Where a.gid = 15 And b.gid = 16

Nasıl bu sorguyu hızlandırmak ve masada uzamsal bir dizin ekledi merak ediyordum:

CREATE INDEX table_way_gist ON table USING gist(way);

Ama aslında hızlanma görmüyorum. ST_Contains sorguları yapmadan ÖNCE tabloyu tüm çokgenlerle doldurduktan SONRA indeksi oluşturuyorum. Bir tabloyu doldurmadan önce indeks eklenmeli mi? Tabloda dizinle çalışmak için özel gereksinimler var mı? Geometrik sütun yolunun izdüşümü (srid) 900913 olarak ayarlanmıştır.

Kullanıyorum: psql (PostgreSQL) 9.1.4 / POSTGIS = "1.5.3"

Yanıtlar:


16

Sorunuzda ifade edilen sorgunun en etkili dizini , bir where ifadesinde görünen tek sütun olduğu için gid kodudur :

 CREATE INDEX table_gid ON table (gid);

Sadece yer kaplayacağı ve yavaş ekler / güncellemeler / sileceği için gist dizinini güvenle bırakabilirsiniz.

Uzun açıklama

Dediğim gibi sizin durumunuzda en etkili endeksi gid bir db motoru satırları daha hızlı almak için izin verecek gibi (alma genellikle sürecin en yavaş parçası olan). Bundan sonra, muhtemelen sonucu daha iyi hesaplayacaktır.

  ST_Contains(a.way, b.way)

endekse bakmadan espression. Nedeni ararken ekstra maliyet Sorgu planlayıcısı olasılıkla tahmin edecektir özü hem sütunlarda endeksi karşı ararken a.way ve b.way doğrudan değerleri değerinde bakmak için toplam satır sayısı olarak çaba değil özellikle dizin benzersizse muhtemelen çok küçüktür.

Genel bir kural olarak, planlayıcının muhtemelen küçük veri kümeleri için bir dizin taraması üzerinden bir tablo taramasını tercih edeceğini unutmayın (veri kümesi boyutları tablo istatistiklerine bakarak tahmin edilir).


Bu, sorunu daha net hale getiriyor. Deneyeceğim. Eğer ST_Contains () sorguyu WHERE yan tümcesine koyarsam, uzamsal dizin gerçekten yardımcı olmalıdır? Scriptimi WHERE yan tümcesi içinde ST_Contains'ı çağırmak için yeniden düzenlemem gerektiğini düşünüyorum. Şu anda tüm çokgenleri yineliyorum ve her zaman ikisini ayrı ayrı test ediyorum.
MichiMichbeck

?? mekansal bir endeksin işleri yavaşlattığını mı söylüyorsunuz? Bu benim için yeni, çünkü çalıştığım yerde her bir tablo için mekansal dizinler var ve bunun kötü bir uygulama olup olmadığını merak ediyorum
Luffydude

13

Gibi unicoletti söyledi WHERE ifadesinde ST_Contains () kullanırsanız, geometri sütununda özü endeksi sadece çalışacak.

Örneğin, birbirini içeren tüm çokgenleri bilmek istiyorsanız, şöyle bir şey kullanabilirsiniz:

SELECT a.gid, b.gid
FROM table AS a, table as b
WHERE a.gid != b.gid and ST_Contains(a.way, b.way)

Bu durumda, tablonuzun büyüklüğüne ve geometrilerinizin karmaşıklığına bağlı olarak, gist endeksi önemli bir hız sağlamalıdır, çünkü ST_Contains, tüm geometrilerini gerçekten kontrol etmeden önce sınır kutularını karşılaştırarak çokgenleri filtreleyerek başlayacaktır. OpenGeo Eğiticisinde küçük bir açıklama görebilirsiniz .


Evet, dizin sınır testini dahil etmek için bu sorguya ihtiyacım var. Teşekkürler Alexandre. (Unicoletti'yi hızlı olarak çözdüğüm ve bana sorunu çözdüğü için çözüm olarak işaretleyeceğim)
MichiMichbeck
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.