powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / простой вопрос про select
2 сообщений из 2, страница 1 из 1
простой вопрос про select
    #35206353
untitled
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
непонятно в какой форум писать, поэтому напишу сюда, так как всё нижеописанное происходит под управленим постгре.

задача на первый взгляд простая.
есть большая таблица, под миллиард записей
убрав все лишнее ее можно представить в виде

Код: plaintext
1.
2.
3.
4.
5.
6.
CREATE TABLE "bigtable"
(
  table_id bigint NOT NULL,
  numvalue bigint,
  textvalue text,
) 

то есть здесь хранятся пары данных число-текст

по этой таблице нужно делать выборку следующего вида:

выбрать первые 10 значений numvalue для которых есть пара с текстом 'текст1' а также есть пара с текстом 'текст2', а также есть пара 'текст3' и т.д.

вопрос стоит в том, чтобы сделать этот запрос самым бытрым способом.

самое тупое решение в лоб через intersect работает только в том случае, когда искомых значений в таблице очень мало, в остальных случаях оно безбожно тормозит так как делает выборку по всей таблице:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
select * from (
(select numvalue from bigtable where textvalue='текст1')
intersect
(select numvalue from bigtable where textvalue='текст2')
intersect
(select numvalue from bigtable where textvalue='текст2')
intersect ...
)as foo limit  10 

второе решение, которое приходит в голову это делать запросы вида
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select a.numvalue 
from bigtable a, bigtable b, bigtable c
where 
a.numvalue=b.numvalue and 
b.numvalue = c.numvalue
and 
a.textvalue='текст1' and 
b.textvalue='текст2' and 
c.textvalue='текст3'
limit  10 

оно работает гораздо быстрее первого но все равно, если значение 'текст1' часто встречается в таблице, запрос работает слишком долго.

в итоге я пока остановился вот на таком решении:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
select a.numvalue from bigtable a where 
a.textvalue = 'текст1' 
AND 
((select aaa.numvalue from bigtable aaa where aaa.numvalue = a.numvalue and aaa.textvalue  =  'текст2' limit  1 ) is not null )
AND 
((select aaa.numvalue from bigtable aaa where aaa.numvalue = a.numvalue and aaa.textvalue  =  'текст3' limit  1 ) is not null )

limit  10 

по тестам оно работает быстрее предыдущего запроса, но тоже начинает очень тормозить когда количество условий становится заметно больше трёх.


В общем мне хотелось бы услышать ваши мысли - как можно еще сделать подобную выборку чтобы это было максимально быстро?
...
Рейтинг: 0 / 0
простой вопрос про select
    #35206574
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
untitled... безбожно тормозит ...

... работает слишком долго ...

... начинает очень тормозить ...показывайте EXPLAIN ANALYZE этих запросов

попробуйте при наличии индекса по (textvalue,numvalue) запрос

select numvalue
from bigtable a join bigtable b using (numvalue) join bigtable c using (numvalue)
where a.textvalue='текст1' and b.textvalue='текст2' and c.textvalue='текст3'
order by numvalue limit 10
...
Рейтинг: 0 / 0
2 сообщений из 2, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / простой вопрос про select
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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