Re: [pgsql-ru-general] Дистанция cube, как выбрать ближайшие чтобы из индекса? - Mailing list pgsql-ru-general

From Oleg Bartunov
Subject Re: [pgsql-ru-general] Дистанция cube, как выбрать ближайшие чтобы из индекса?
Date
Msg-id CAF4Au4ysg=ko6=9UXLsRg-hVunNL0H9R6asDMqr3y8QKhCcwMQ@mail.gmail.com
Whole thread Raw
Responses Re: [pgsql-ru-general] Дистанция cube, как выбрать ближайшие чтобы из индекса?  (Stas Kelvich <stas.kelvich@gmail.com>)
List pgsql-ru-general
Вам нужно попробовать патч Стаса для куба, поищите в -hackers за прошлый год. Стас, проясни ситуацию с патчем, плиз.

http://www.postgresql.org/message-id/9E07E159-E405-41E2-9889-A04F534FC257@gmail.com

Олег

2014-10-05 11:33 GMT+04:00 Dmitry E. Oboukhov <unera@debian.org>:
                         Таблица "public.t"
 Колонка |   Тип   |                  Модификаторы
---------+---------+------------------------------------------------
 id      | integer | NOT NULL DEFAULT nextval('t_id_seq'::regclass)
 p       | point   |
Индексы:
    "t_p_gist_idx" gist (p)

INSERT INTO "t"
     SELECT
        generate_series(1, 1000000) AS "id",
        point(random(), random()) AS "p";

EXPLAIN ANALYZE
    SELECT
        "id", point(0.3, 0.3) <-> p
    FROM
        "t"
    ORDER BY
        point(0.3, 0.3) <-> p
    LIMIT 10;

 Limit  (cost=0.29..1.10 rows=10 width=20) (actual time=0.248..0.276 rows=10 loops=1)
   ->  Index Scan using t_p_gist_idx on t  (cost=0.29..81860.29 rows=1000000 width=20) (actual time=0.246..0.269 rows=10 loops=1)
         Order By: (p <-> '(0.3,0.3)'::point)
 Total runtime: 0.320 ms
(4 строки)

Для точек - прям то что надо, работает чистый index scan и лимит.

Продолжаем эксперимент:

ALTER TABLE "t"
    ADD COLUMN "c" cube NOT NULL
        DEFAULT cube(ARRAY[random(), random(), random(), random()]);

CREATE INDEX "t_c_gist_idx" ON "t" USING GIST ("c");

Далее выбираем ближайшие кубы по аналогии с точками

EXPLAIN ANALYZE
    SELECT
        "id", cube_distance("c", cube(ARRAY[0.3,0.3,0.3,0.3])) AS "dist"
    FROM
        "t"
    ORDER BY
        cube_distance("c", cube(ARRAY[0.3,0.3,0.3,0.3]))
    LIMIT 10;


 Limit  (cost=49494.64..49494.67 rows=10 width=36) (actual time=791.093..791.098 rows=10 loops=1)
   ->  Sort  (cost=49494.64..51994.64 rows=1000000 width=36) (actual time=791.090..791.092 rows=10 loops=1)
         Sort Key: (cube_distance(c, '(0.3, 0.3, 0.3, 0.3)'::cube))
         Sort Method: top-N heapsort  Memory: 25kB
         ->  Seq Scan on t  (cost=0.00..27885.00 rows=1000000 width=36) (actual time=0.041..507.259 rows=1000000 loops=1)
 Total runtime: 791.137 ms
(6 строк)


То есть видно что в случае с точками выборка ближайших соседей -
выборка нескольких элементов из индекса.

в случае с кубом - это еще и сортировка всей таблицы из миллиона
элементов.

соответственно для точек получается 0.3мс, для кубов 791 мс.


я так полагаю что cube не определяет дистанцию для индекса, либо я
как-то не включил ее использование.

Вопрос: как привести EXPLAIN по cube к такому же виду как по point?

--

. ''`.                               Dmitry E. Oboukhov
: :’  :   email: unera@debian.org jabber://UNera@uvw.ru
`. `~’              GPGKey: 1024D / F8E26537 2006-11-21
  `- 1B23 D4F8 8EC0 D902 0555  E438 AB8C 00CF F8E2 6537

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)

iEYEAREDAAYFAlQw9E0ACgkQq4wAz/jiZTdhwACfRr9PIppB1cJ0egIExvXzH9cp
pIAAoKHEpNeFRZPxE+VV52oUCmZ4ecST
=XLdI
-----END PGP SIGNATURE-----


pgsql-ru-general by date:

Previous
From: "Dmitry E. Oboukhov"
Date:
Subject: Дистанция cube, как выбрать ближайшие чтобы из индекса?
Next
From: Nikolay Samokhvalov
Date:
Subject: Митап #PostgreSQLRussia в компании Avito.ru