Uzamsal bir indeksi ne zaman kullanmamalısınız?


29

Bunu soruyorum çünkü çoğunlukla Oracle ile çalışıyordum ama geçen yıl PostGIS ve SQLServer 2008 ile iki katına çıktım. Oracle'daki en uzamsal işlevler ORA-13226 hatasını döndüren uzamsal bir dizin olmadan çalışmaz:

13226, 00000, "arabirim uzamsal bir dizin olmadan desteklenmiyor" // * Neden: Geometri tablosunun uzamsal bir dizini yok. // * Eylem: Uzamsal operatörde referans verilen geometri tablosunun üzerinde uzamsal bir dizin olduğunu doğrulayın.

Bana göre bu mantıklı. Uzamsal bir sorgu çalıştırıyorsanız = uzamsal bir dizine sahip olmalısınız. Ama anladığım kadarıyla, ne PostGIS ne de SQL Serve bunu gerektirmiyor. PostGIS, KESİNLİKLE, uzamsal dizini kullanmayacak işlevlere (_ * örneğin _STContains) sahip görünüyor.

Öyleyse soru, mekansal bir endeks kullanmamanız gereken durumlar var mı? Mutlaka bir 'al ya da bırak' yaklaşımı olsun olmasın, yani herhangi bir fark yaratmayacak, ama mekansal endeksini kullanmayan yerlerde performansı artıracak mı? Bana göre, son cümle terimlerdeki bir çelişkidir, ancak aksi halde PostGIS neden bu işlevleri sağlar?


3
Eğer bir indeksin PostGIS SET içindeki işleri daha yavaş hale getirdiğini görmek istiyorsanız enable_seqscan = off. Bu PostgreSQL'i her zaman indeks kullanmaya zorlar. Hızları bununla karşılaştırın.
Sean,

Bu konuyu başlattığın için teşekkürler. İnternetteki bilgimin üzerine dökülüyorum, örgütünün (hükümetin) neden oracle / sde özellik sınıfları ve tablolarındaki uzamsal (ve hatta nitelik) endekslerini kullanmadığını anlamaya çalışıyorum. Şimdi onlara sunmak için birkaç tartışmam var, bu yüzden saçımı çıkarmam gerekmeyecek, kendileri için bir sorgu bekleyeceğim.
Mike,

Yanıtlar:


12

mapoholic,

Genel olarak konuşursak, gerçekten küçük tablolarla uğraşmadığınız sürece, uzamsal indeks olmadan uzamsal bir sorgu yapmak için bir neden yoktur. Yine de, bir indeks kullanmayan ancak & & indexable kısa devre kutusu operatörüne sahip olan ST_'yi kullanmanıza rağmen. _ST ile başlayan fonksiyonların son kullanıcılar tarafından kullanılması amaçlanmamıştır. Var olmalarının nedeni, zorunda olmalarıdır. PostGIS uzaysal dizinleri, dizinin kullanımını zorlamak için SQL satır içi kullanır - _ST genellikle GEOS tarafından yapılır ve && yeniden sıralanabilecek dizindir. Yani _ST gerçekten bir uygulama eseridir.

bu yüzden kısaca tek bir fonksiyon değildir, böylece daha yoğun mekansal kontrolden önce endeks işleminin bir kerede gerçekleşmesi için yeniden sıralanabilir.


Şerefe LR1234567. Sanırım aradığım şey buydu.
mapoholic

25

Veri kümeniz sık sık eklenir ve güncellenirse, dizinin yeniden oluşturulmasına neden olan INSERT, DELETE ve UPDATE deyimleri veritabanını yavaşlatabilir.

Tüm OSM veri kümesini bir veritabanına yüklemek gibi toplu ekler için, dizinleri bırakmak ve daha sonra bunları tekrar oluşturmak daha hızlı olabilir.

Bir dizini yoksaymak daha verimli ise (örneğin, tablo belleğe yüklenecek kadar küçükse), veritabanı sorgu işlemcisi bunu otomatik olarak yapmalıdır.

Sorguların uzamsal bir dizin olmadan çalıştırılmasına izin vermek için ana neden, bir dizin kullanarak elde ettiğiniz performans avantajlarını, düşürmek zorunda kalmadan ölçmektir.

Son olarak, sorgularda ve harita gösterimlerinde büyük bir performans artışı göstermek istiyorsanız, sistem geliştirmede uygun bir an için endeks oluşturmayı geciktirmek isteyebilirsiniz ...


3
(+1) Bu son sözde biraz sinizm tespit ediyor muyum? :-)
whuber

Hiç değil ;-) Ancak dikkatlice ayarlanmış endeksleri düşürmek / yeniden oluşturmak, "X neden veritabanı değişikliklerinde çok zaman harcandı?"
geographika

Coğrafyaya teşekkürler, ve ben de Whuber'un sözlerine katılıyorum! ;-) Toplu yükleme yapılırken uzamsal endeksleri (veya konuyla ilgili tüm endeksleri) düşürdüğün / devre dışı bırakacağınızı anlıyorum; Bir tablo yeterince küçükse, dizini kullanmak yeterli bir fark yaratabilir - ancak dizini kullanmamayı mı seçebilir? Bilmiyorum, sanırım PostGIS mekansal olmayan indeks fonksiyonlarının varlığıyla daha da şaşırdım ...
mapoholic

2
Bir tablo yeterince küçükse ve belleğe sığarsa, bir dizin kullanmak, sıralı bir tarama yapmaktan daha pahalı olan rasgele disk erişimini gerektirir. wiki.postgresql.org/wiki/…
Sean, 14

2
@mapoholic - _ST_Contains, verilerinizin ön filtresini elle yapmak zorunda kaldığınız zamandan
geographika

10

Bu ima düşünüyorum, ama olur DEĞİL ben yerine kullanabileceği bir mekansal olmayan indeksi vardı bir sorgu için bir mekansal dizinini kullanırız. Örneğin, ABD’yi masaya yükleyen 2.113.450 puanım var. Alaska eyaletindeki tüm noktaları çekmek istersem, GIST indeksini nokta geometrilerinde kullanarak Alaska eyaletinin geometrisine göre karşılaştırmak için bir uzaysal sorgusu yapabilirdim. "state_alpha" olan tüm noktaları döndürmek için nokta verilerindeki "state_alpha" alanı (aynı zamanda dizine alınır) = 'AK'.

“Bunun mekansal kısmı nerede” diye soruyorsunuz? Peki, onları topladıktan sonra Alaska noktalarında bazı uzamsal analizler yapmam gerekirse, önce mekansal olmayan bir sorgu kullanarak bu nokta geometrilerini toplamak daha hızlı olur. Ayrıca, gerçekten büyük veri kümeleri için bir arama alanı (veya tablo) eklemekten faydalandığınız anlamına gelir. Yine, bunun muhtemelen herkes için açıkça belli olduğunu biliyorum, yalnızca bahsetmiştim, çünkü geçmişte yalnızca mekansal olarak endekslenmiş ve ortak bir sorgunun "bir ülke içindeki tüm özellikler" olduğu küresel veri setleriyle karşılaştığım için. İndekslenmiş bir country_fips alanı ekleyerek çok fazla performans elde ettik.

Aşağıda, bu konuyu ispatlayan EXPLAIN ANALYZE sonuçları verilmiştir. (NOT: Mekansal sorguyu bir BBOX sorgusu kullanarak mümkün olduğunca verimli hale getirmeye çalıştım. Durum anahatlarını kullanmak sadece daha yavaş yapacaktır.)

# explain analyze select count(*) from gnis_names where state_alpha = 'AK';
Aggregate  (cost=57359.45..57359.46 rows=1 width=0) (actual time=76.606.. 76.607 rows=1 loops=1)
<snip>
Total runtime: 76.676 ms

# explain analyze select count(*) from gnis_names where the_geom && GeomFromText('POLYGON((-179.14734 51.219862,-179.14734 71.3525606439998,179.77847 71.3525606439998,179.77847 51.219862,-179.14734 51.219862))',4326);
Aggregate  (cost=27699.86..27699.87 rows=1 width=0) (actual time=86.523..86.524 rows=1 loops=1)
<snip>
Total runtime: 86.584 ms 

Bunun için çok teşekkürler. Bunu söylerken çok açık gözükebilir, ama ilk düşüncem, yalnızca bir öznitelik değil, uzamsal bir sorgu yapmak olacaktır. Bunun için +1!
mapoholic

0

Bu ifadeyi henüz fark ettim

Bana göre bu mantıklı. Uzamsal bir sorgu çalıştırıyorsanız = uzamsal bir dizininiz olmalıdır

Bana göre bu hiç mantıklı gelmiyor ve bence hem SQL Server hem de Postgis daha iyi bir iş çıkarıyor ya da en azından performans ayrıntılarıyla sizi rahatsız etmiyor. Aslında, hem SQL Server hem de Postgis bazen uzamsal dizini bile kullanmıyor (tam tablo taramasına geri dönüyor).

Oracle için, dizini oluşturmalısınız ve bu nedenle user_sdo_geom_metadata'yı doldurmalısınız.

Bunu sadece alfanümerik indekslerle karşılaştırarak performans nedenleriyle varlar, SQL deyiminiz onunla ve onunla çalışmalı.

Oracle veritabanında, dizini bırakın; mekansal sorguları kullanamayacak kadar çok sayıda hata ve uygulama alacaksınız, bu nedenle çalışmaz.

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.