SORU
29 Aralık 2011, PERŞEMBE


En iyi seç rastgele satır yol PostgreSQL

Satır rasgele bir seçim PostgreSQL, bunu denedim istiyorum:

select * from table where random() < 0.01;

Ama başka bir tavsiye:

select * from table order by random() limit 1000;

500 Milyon satır ile çok büyük bir tablo var, hızlı olmak istiyorum.

Hangi yaklaşım daha iyi? Farklar nelerdir? Rastgele satır seçmek için en iyi yolu nedir?

CEVAP
30 Aralık 2011, Cuma


Özellikleri (artı yorum ek bilgi) verilmiş

  • Sadece birkaç boşluklar ile id sayısal bir sütun var.
  • Ortada tek bir ya da birkaç yazma işlemleri.
  • id sütun endeksli olmalı! Birincil anahtar güzel hizmet vermektedir.

Sorgu altındaçok daha hızlı. Bir sıralı büyük tablo, dizin tarama sadece tarama gerekmez.

İlk olarak, ana sorgu için tahminleri alabilir:

SELECT count(*) AS ct              -- optional
     , min(id)  AS min_id
     , max(id)  AS max_id
     , max(id) - min(id) AS id_span
FROM   bigtbl;

Orta derecede pahalı tek parça count(*). Yukarıdaki özellikleri göz önüne alındığında, gerek yok. Bir tahmin sadece, neredeyse hiç maliyeti (detailed explanation here) en iyi kullanılabilir:

SELECT reltuples AS ct FROM pg_class WHERE oid = 'schema_name.bigtbl'::regclass;

ct büyüklük id_span daha küçük olduğu sürece, sorgu diğer yaklaşımlar geride bırakacaktır.

WITH params AS (
    SELECT 1       AS min_id           -- minimum id <= current min id
         , 5100000 AS id_span          -- rounded up. (max_id - min_id   buffer)
    )
SELECT *
FROM  (
    SELECT p.min_id   trunc(random() * p.id_span)::integer AS id
    FROM   params p
          ,generate_series(1, 1100) g  -- 1000   buffer
    GROUP  BY 1                        -- trim duplicates
    ) r
JOIN   bigtbl USING (id)
LIMIT  1000;                           -- trim surplus
  • id uzayda rastgele sayılar üretir. ""Ekleyin ki 10 % (kolayca boşlukları karşılayacak kadar) almak için satır sayısı. birkaç boşluklar var

  • id Her şans (çok olası büyük bir kimlik alanı ile olsa da) tarafından birden fazla kez alınabilir, oluşan rakamlar (veya DISTINCT) grup.

  • Büyük masa için ids katıl. Bu çok hızlı yerine dizin olmalıdır.

  • Son olarak trim fazlası ids O yapay genler ve boşluklar tarafından yenmiş. Her bir satır vareşit şans tamamentoplanmış olmalıdır.

Kısa versiyon

Yapabilirsinizbasitleştirmekbu sorguyu. Sorguda CTE yukarıda sadece eğitim amaçlı

SELECT *
FROM  (
    SELECT DISTINCT 1   trunc(random() * 5100000)::integer AS id
    FROM   generate_series(1, 1100) g
    ) r
JOIN   bigtbl USING (id)
LIMIT  1000;

Olası alternatif

Gereksinimlerinizi izin verirsetekrar aynı ayarlararamalar (ve çağrılar bahsediyoruz) bir düşününgörünüm, hayata. Yukarıdaki sorgu bir kez çalıştırmak ve sonuç tabloya yazın. Kullanıcılar hız aydınlatma at yarı rastgele bir seçim olsun. Aralıklarla veya seçtiğiniz olaylar rastgele seç yenile.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • andony5589

    andony5589

    7 Aralık 2011
  • Britec09

    Britec09

    4 Mart 2009
  • Jason Parker

    Jason Parker

    14 Aralık 2009