powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / tsvector, GIN index и seq_scan
6 сообщений из 6, страница 1 из 1
tsvector, GIN index и seq_scan
    #35296959
cg2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
cg2
Гость
Здравствуйте !

Есть таблица №1:

CREATE TABLE title_index
(
"Id" integer NOT NULL,
"Flag" integer,
"OType" character varying(255),
"OStatus" integer,
"PStatus" integer,
"TSVect" tsvector,
CONSTRAINT "title_index_Id_pk" PRIMARY KEY ("Id")
)

CREATE INDEX "title_TSVect_GIN_idx"
ON title_index
USING gin
("TSVect");

Есть таблица №2:

CREATE TABLE page_index
(
"Id" integer NOT NULL,
"Flag" integer,
"PuStatus" integer,
"PaStatus" integer,
"TSVect" tsvector,
CONSTRAINT "page_index_Id_pk" PRIMARY KEY ("Id")
)

CREATE INDEX "page_TSVect_GIN_idx"
ON page_index
USING gin
("TSVect");

В таблице №1 хранятся короткие "заголовки текстов".
Свойства таблицы №1:
Table size: 104 kB
Toast table size: 8192 bytes
Indexes Size: 136 kB
Rows (counted): 413

В таблице №2 хранятся "тексты" большой длины.
Свойства таблицы №2:
Table size: 40 kB
Toast table size: 5624 kB
Indexes Size: 9080 kB
Rows (counted): 245

Запрос к таблице №1:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
EXPLAIN ANALYZE 
SELECT ts_rank ("TSVect", query) as rank,
"Id",
FROM title_index,
to_tsquery ('ГЛАВА') as query
WHERE ("TSVect" @@ query)
AND "OType" = 'page'
AND "Flag" =  1 
AND "PStatus" =  1 
AND "OStatus" =  1 
ORDER BY rank DESC;

дает план:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
Sort  (cost= 8 . 32 .. 8 . 32  rows= 1  width= 142 ) (actual time= 4 . 040 .. 4 . 815  rows= 245  loops= 1 )
  Sort Key: (ts_rank(title_index."TSVect", query.query))
  Sort Method:  quicksort  Memory: 26kB
  ->  Nested Loop  (cost= 0 . 00 .. 8 . 31  rows= 1  width= 142 ) (actual time= 0 . 166 .. 3 . 162  rows= 245  loops= 1 )
        ->  Function Scan on to_tsquery query  (cost= 0 . 00 .. 0 . 01  rows= 1  width= 32 ) (actual time= 0 . 053 .. 0 . 057  rows= 1  loops= 1 )
        ->  Index Scan using "title_TSVect_GIN_idx" on title_index  (cost= 0 . 00 .. 8 . 28  rows= 1  width= 110 ) (actual time= 0 . 093 .. 1 . 320  rows= 245  loops= 1 )
              Index Cond: (title_index."TSVect" @@ query.query)
              Filter: (((title_index."OType")::text = 'page'::text) AND (title_index."Flag" =  1 ) AND (title_index."PStatus" =  1 ) AND (title_index."OStatus" =  1 ))
Total runtime:  5 . 690  ms

А запрос к таблице №2:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
EXPLAIN ANALYZE
SELECT ts_rank ("TSVect", query) as rank,
"Id",
FROM page_index,
to_tsquery ('ГЛАВА') as query
WHERE ("TSVect" @@ query)
AND "Flag" =  1 
AND "PuStatus" =  1 
AND "PaStatus" =  1 
ORDER BY rank DESC;

дает план:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
Sort  (cost= 12 . 07 .. 12 . 08  rows= 1  width= 80 ) (actual time= 92 . 685 .. 92 . 823  rows= 43  loops= 1 )
  Sort Key: (ts_rank(page_index."TSVect", query.query))
  Sort Method:  quicksort  Memory: 18kB
  ->  Nested Loop  (cost= 0 . 00 .. 12 . 06  rows= 1  width= 80 ) (actual time= 1 . 205 .. 92 . 405  rows= 43  loops= 1 )
        Join Filter: (page_index."TSVect" @@ query.query)
        ->  Function Scan on to_tsquery query  (cost= 0 . 00 .. 0 . 01  rows= 1  width= 32 ) (actual time= 0 . 372 .. 0 . 377  rows= 1  loops= 1 )
        ->  Seq Scan on page_index  (cost= 0 . 00 .. 9 . 11  rows= 235  width= 48 ) (actual time= 0 . 019 .. 1 . 089  rows= 245  loops= 1 )
              Filter: ((page_index."Flag" =  1 ) AND (page_index."PuStatus" =  1 ) AND (page_index."PaStatus" =  1 ))
Total runtime:  93 . 031  ms

Собственно, вопрос:

Почему во втором случае PostgreSQL выбирает Seq Scan, даже если я ему говорю "SET enable_seqscan TO OFF;" перед этим и GIN индекс существует?
Можно ли его заставить использовать индекс?
...
Рейтинг: 0 / 0
tsvector, GIN index и seq_scan
    #35298423
ЯЕХХ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Проще всего - переписать запрос на вложенный
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
SELECT * FROM (
SELECT ts_rank ("TSVect", query) as rank, *
FROM page_index,
to_tsquery ('ГЛАВА') as query
WHERE ("TSVect" @@ query)
ORDER BY rank DESC
) t
WHERE "Flag" =  1 
AND "PuStatus" =  1 
AND "PaStatus" =  1 
тут оптимизатору деваться будет некуда

И может сделать единую таблицу с разделением веса заголовков/страниц через setweight()?
...
Рейтинг: 0 / 0
tsvector, GIN index и seq_scan
    #35299408
cg2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
cg2
Гость
Попробовал с вложенным запросом, вот результат:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
Sort  (cost= 17 . 05 .. 17 . 05  rows= 1  width= 105 ) (actual time= 128 . 390 .. 128 . 499  rows= 34  loops= 1 )
  Sort Key: (ts_rank(page_index."TSVect", query.query))
  Sort Method:  quicksort  Memory: 21kB
  ->  Nested Loop  (cost= 0 . 00 .. 17 . 04  rows= 1  width= 105 ) (actual time= 1 . 769 .. 128 . 088  rows= 34  loops= 1 )
        Join Filter: (page_index."TSVect" @@ query.query)
        ->  Function Scan on to_tsquery query  (cost= 0 . 00 .. 0 . 01  rows= 1  width= 32 ) (actual time= 0 . 377 .. 0 . 382  rows= 1  loops= 1 )
        ->  Seq Scan on page_index  (cost= 0 . 00 .. 12 . 85  rows= 334  width= 73 ) (actual time= 0 . 019 .. 1 . 681  rows= 357  loops= 1 )
              Filter: ((page_index."Flag" =  1 ) AND (page_index."PuStatus" =  1 ) AND (page_index."PaStatus" =  1 ))
Total runtime:  128 . 709  ms

Не помогло вообщем.
Я даже reindex делал...
...
Рейтинг: 0 / 0
tsvector, GIN index и seq_scan
    #35299413
cg2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
cg2
Гость
А setweight() да, прикольная штука.
Надо будет попробовать.
...
Рейтинг: 0 / 0
tsvector, GIN index и seq_scan
    #35302287
Фотография ss25
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
Rows (counted):  245 
Код: plaintext
Rows (counted):  413 

на таких объемах индекс не нужен.

попробуйте тоже самое на таблицах от 5К строк.
...
Рейтинг: 0 / 0
tsvector, GIN index и seq_scan
    #35302539
cg2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
cg2
Гость
Да, возможно так и должно быть.
Но меня смущает вот что:
почему при поиске в таблице, где хранятся маленькие заголовки
в небольшом количестве индекс используется, а там, где лежат большие тексты - нет.
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / tsvector, GIN index и seq_scan
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]