SELECT Count(id) FROM A where A.b IN ( SELECT z FROM B WHERE xxxx) работает 20 секунд, в то время как SELECT Count(id) FROM A where A.b IN ( SELECT DISTINCT z FROM B WHERE xxxx)0.02 сек
( Read more... )
Понятно, что, в общих чертах, там выполняется следующая работа:
Либо так: - линейный забег по B за время O(Nb), построили несортированный набор z размером Nz - по желанию, отсортировали его за O(Nz * log Nz) - линейный забег по A размером Na, проверяя каждый элемент за O(Na * Nz) либо O(Na * log Nz)
Либо этак: пересечение множеств - ленивый линейный забег по неуникальному индексу B.z, - как только находим значение в строке, удовлетворяющей xxxx, перескакиваем через все оставшиеся дубликаты z - ленивый линейный забег по неуникальному индексу A.b, перепрыгивая через дубликаты (суммируя их количество)
Самый наивный алгоритм даёт выигрыш, если Nz большое, а Na маленькое - т.е. если затраты на сортировку превышают потери на линейный поиск. А самый продвинутый требует наличия предварительно построенных индексов.
Если индексы построить, то постгрес поумнеет или всё равно будет тупить без distinct?
select count(id) from transactions where msg='__subscribe__' and date >=%s and date <%s and sub_id in (select DISTINCT sub_id from selllog where source_id=%s and target_id=%s and date>=%s and date < %s)
Интересно, а честный иннер-джойн ещё сильнее тупить будет?
select count(id) from transactions as T inner join selllog as S on T.sub_id = S.sub_id where T.msg='__subscribe__' and T.date >= ? and T.date < ? and S.source_id = ? and S.date >= ? and S.date < ?
Вы владелец сообщества ru_gnostik? Модераторы почему-то перестали за ним следить, и сообщения отправленные туда зависают в очереди (притом и не отклоняются). Если вы не против, прошу включить меня в состав модераторов, я давно и много туда пишу. Можете посмотреть сами.
Comments 14
Понятно, что, в общих чертах, там выполняется следующая работа:
Либо так:
- линейный забег по B за время O(Nb), построили несортированный набор z размером Nz
- по желанию, отсортировали его за O(Nz * log Nz)
- линейный забег по A размером Na, проверяя каждый элемент за O(Na * Nz) либо O(Na * log Nz)
Либо этак:
пересечение множеств
- ленивый линейный забег по неуникальному индексу B.z, - как только находим значение в строке, удовлетворяющей xxxx, перескакиваем через все оставшиеся дубликаты z
- ленивый линейный забег по неуникальному индексу A.b, перепрыгивая через дубликаты (суммируя их количество)
Самый наивный алгоритм даёт выигрыш, если Nz большое, а Na маленькое - т.е. если затраты на сортировку превышают потери на линейный поиск.
А самый продвинутый требует наличия предварительно построенных индексов.
Если индексы построить, то постгрес поумнеет или всё равно будет тупить без distinct?
Reply
Всё равно тупит.
Reply
select count(id) from transactions where msg='__subscribe__' and date >=%s and date <%s and sub_id in (select DISTINCT sub_id from selllog where source_id=%s and target_id=%s and date>=%s and date < %s)
Индексы по всем полям.
Reply
select count(id)
from transactions as T
inner join selllog as S
on T.sub_id = S.sub_id
where T.msg='__subscribe__' and T.date >= ? and T.date < ?
and S.source_id = ? and S.date >= ? and S.date < ?
По смыслу-то ведь именно это делается?
Reply
Модераторы почему-то перестали за ним следить, и сообщения отправленные туда зависают в очереди (притом и не отклоняются). Если вы не против, прошу включить меня в состав модераторов, я давно и много туда пишу. Можете посмотреть сами.
Reply
Reply
Leave a comment