Bölüm kısıtlaması, zaman damgası ile bölümlenmiş tabloları içeren birleşimler için kullanılmaz


11

Ben gibi bir bölümlenmiş tablo yapısı var:

CREATE TABLE measurements (
    sensor_id bigint,
    tx timestamp,
    measurement int
);

CREATE TABLE measurements_201201(
    CHECK (tx >= '2012-01-01 00:00:00'::timestamp without time zone 
       AND tx < ('2012-01-01 00:00:00'::timestamp without time zone + '1 mon'::interval))    
)INHERITS (measurements);
CREATE INDEX ON measurements_201201(sensor_id);
CREATE INDEX ON measurements_201201(tx);
CREATE INDEX ON measurements_201201(sensor_id, tx);
....

Ve bunun gibi. Her tablonun yaklaşık 20M satırı vardır.

Ben bir sensör örnekleri ve WHEREyan tümcesinde zaman damgası örneği için sorgu, sorgu planı seçilen doğru tabloları gösterir ve kullanılan dizinler örn:

SELECT *
FROM measurements
INNER JOIN sensors TABLESAMPLE BERNOULLI (0.01) USING (sensor_id)
WHERE tx BETWEEN '2015-01-04 05:00' AND '2015-01-04 06:00' 
    OR tx BETWEEN '2015-02-04 05:00' AND '2015-02-04 06:00' 
    OR tx BETWEEN '2014-03-05 05:00' AND '2014-04-07 06:00' ;

Ancak, bir CTE kullanırsanız veya zaman damgası değerlerini bir tabloya koyarsam (geçici tablodaki dizinlerle bile gösterilmez).

WITH sensor_sample AS(
    SELECT sensor_id, start_ts, end_ts
    FROM sensors TABLESAMPLE BERNOULLI (0.01)
    CROSS JOIN (VALUES (TIMESTAMP '2015-01-04 05:00', TIMESTAMP '2015-01-04 06:00'),
        (TIMESTAMP '2015-02-04 05:00', TIMESTAMP '2015-02-04 06:00'),
        (TIMESTAMP  '2014-03-05 05:00', '2014-04-07 06:00') ) tstamps(start_ts, end_ts)
)

Aşağıdaki gibi bir şey

SET constraint_exclusion = on;
SELECT * FROM measurements
INNER JOIN sensor_sample USING (sensor_id)
WHERE tx BETWEEN start_ts AND end_ts

Her tabloda bir dizin taraması gerçekleştirir. Bu hala nispeten hızlıdır, ancak sorguların karmaşıklığının artmasıyla, bu, bölünmüş tabloların sınırlı bir alt kümesinden (4-5 / 50) ~ 40K satırları almak için çok yavaş olacak olan seq taramalarına dönüşebilir.

Ben böyle bir şey endişe ediyorum bu sorundur.

Önemsiz ifadeler için, Postgres sorgu planlayıcısının CHECK kısıtlamasına güvenebileceğini anlamasını sağlamak için sorgularda az çok kelimesi kelimesini tekrarlamanız gerekir. Gereksiz görünse bile!

Tüm verilerimde seq taraması yapma olasılığını azaltmak için bölümleme ve sorgu yapısını nasıl geliştirebilirim?


1
harika bir soru - ancak EXPLAIN (
ANALİZ

Yanıtlar:


1

Kısıtlamaya dayalı dışlama [CBE], sorgu ayrıştırıldıktan, gerçek ilişkilere eşlendikten ve yeniden yazıldıktan hemen sonra sorgu planlamasının erken aşamasında gerçekleştirilir. ( dahili araçlar, Planlayıcı / Optimize Edici aşaması)

Planlayıcı "sensor_sample" tablosunun herhangi bir içeriğini üstlenemez.

Bu nedenle, sorguda sabit kodlanmış değerleriniz yoksa, planlayıcı "bölümleri" hariç tutmaz.

CTE varyantı ile ne olacağını tahmin ediyorum ... TABLESAMPLE kullandığınız ve alt sorgudaki değişmez değerler statik olsa bile tüm alt sorgu uçucu olarak değerlendirilebileceği için planlayıcı kısıtlanmıştır. ( bu sadece benim tahminim, planlayıcı kodunda uzman değilim )

Parlak tarafta, negatif sonuç ile indeks taraması çok hızlıdır. (en fazla tek sayfa tarama!) Bu yüzden 10000'den fazla bölümünüz olmadıkça, rahatsız olmaz.

Yani, sorunuzu doğrudan cevaplamak için:

  • Bu veri yapısını daha fazla geliştiremezsiniz.

  • Regardin indeks taramaları - ucuzdur;

  • Sıralı taramalarla ilgili olarak - kendi örneklerinizde gördüğünüz gibi, mümkün olduğunda bunlardan kaçınılır.

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.