powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / интересно ...
11 сообщений из 11, страница 1 из 1
интересно ...
    #34370936
Мишган-кабанчик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
имеем запрос
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select * from 
(
     select row_id from tb1 k
            order by
            (
                ( SUBSTR(row_id,  1 ,  2 )::integer ) *  1000000  + ( SUBSTR(row_id,  4 ,  8 ) :: integer)
            )
            desc
) u INNER JOIN tb1 a ON u.row_id=a.row_id
limit  100 
(формат поля row_id: 'xx/xxxx')
при выполении все записи отсортированы, но если убрать последнюю строку (limit 100) то сортировки нету, т.е. записи идут в хаотичном порядке ... почему?
...
Рейтинг: 0 / 0
интересно ...
    #34371175
Мишган-кабанчик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
проведя некоторые исследования, получил следующие показатели, а именно
при значении limit 10000 записи отсортированы как надо но если увеличить например до 20000 записей, то записи начинают идти в хаотичном порядке ... ( в таблице порядка 40000~ ).
В чем прикол... буду рад если объясните почему так происходит :)
...
Рейтинг: 0 / 0
интересно ...
    #34371260
st_serg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
мне думается, вот почему
7.5. Sorting Rows
After a query has produced an output table (after the select list has been processed) it can optionally be sorted. If sorting is not chosen, the rows will be returned in an unspecified order. The actual order in that case will depend on the scan and join plan types and the order on disk , but it must not be relied on. A particular output ordering can only be guaranteed if the sort step is explicitly chosen.
...
Рейтинг: 0 / 0
интересно ...
    #34371344
Andrey Daeron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мишган-кабанчикпроведя некоторые исследования, получил следующие показатели, а именно
при значении limit 10000 записи отсортированы как надо но если увеличить например до 20000 записей, то записи начинают идти в хаотичном порядке ... ( в таблице порядка 40000~ ).
В чем прикол... буду рад если объясните почему так происходит :)
Дык все просто. Читаем матчасть.
Для того что бы отобрать первые n записей должно быть определено отношения порядка записей.
В запросе порядок не указан. Соотвественно это лично постгресовское дело как его ввести (в доке так и написано). При изменении константы меняется план/механизм выполнения запроса (может чего кешируется или еще чего) - вот оно то сортирует (для внутренних нужд) или нет.
...
Рейтинг: 0 / 0
интересно ...
    #34371398
Jelis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Мишган-кабанчикимеем запрос
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select * from 
(
     select row_id from tb1 k
            order by
            (
                ( SUBSTR(row_id,  1 ,  2 )::integer ) *  1000000  + ( SUBSTR(row_id,  4 ,  8 ) :: integer)
            )
            desc
) u INNER JOIN tb1 a ON u.row_id=a.row_id
limit  100 
(формат поля row_id: 'xx/xxxx')
при выполении все записи отсортированы, но если убрать последнюю строку (limit 100) то сортировки нету, т.е. записи идут в хаотичном порядке ... почему?

Да, потому что на основной селект сортировки нет, поэтому и выводит как карта ляжет (т..е как сказал st_serg).
А может просто переписать таким вот образом:
Код: plaintext
1.
2.
3.
4.
SELECT * 
FROM tb1 AS t1
INNER JOIN tb1 AS t2 ON t1.row_id = t2.row_id
ORDER BY (( SUBSTR(t1.row_id,  1 ,  2 )::integer ) *  1000000  + ( SUBSTR(t1.row_id,  4 ,  8 ) :: integer)) DESC

И разрешите поинтересоваться, а зачем вам self join по одному и томуже полю? Ведь это, по идее, просто каждое поле будет дублироваться (если row_id уникальный)? Или вы привели не "боевой" запрос, а просто как пример?
...
Рейтинг: 0 / 0
интересно ...
    #34373050
Мишган-кабанчик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
реальный запрос намного больше, просто этот по сути похож.
Запросец, был под ораклёвую базу... Под оракулом запрос выглядит немного по другому:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
select /*+FIRST_ROWS*/ * from 
(
     select row_id from tb1 k
            order by
            (
                ( SUBSTR(row_id,  1 ,  2 )::integer ) *  1000000  + ( SUBSTR(row_id,  4 ,  8 ) :: integer)
            )
            desc
) u INNER JOIN tb1 a ON u.row_id=a.row_id
вобщем-то всё дело в хинте (реально надо, что-бы как можно быстрее возвращались первые строки),
а засчет того, что внутренний запрос выбирает только 1 поле ... то и время его выполнения намного меньше (2 Jelis не верите сравните мой и ваш запрос, мой отрабатывается 20 сек , ваш - 97, есть индекс на row_id - btree, ессно под Postgres).
...
Рейтинг: 0 / 0
интересно ...
    #34374831
Jelis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вы, кстати, попробуйте еще сделать индекс на ( SUBSTR(row_id, 1, 2)::integer ) * 1000000 + ( SUBSTR(row_id, 4, 8) :: integer)
...
Рейтинг: 0 / 0
интересно ...
    #34374900
Jelis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Мишган-кабанчик
вобщем-то всё дело в хинте (реально надо, что-бы как можно быстрее возвращались первые строки),
а засчет того, что внутренний запрос выбирает только 1 поле ... то и время его выполнения намного меньше (2 Jelis не верите сравните мой и ваш запрос, мой отрабатывается 20 сек , ваш - 97, есть индекс на row_id - btree, ессно под Postgres).

Вполне, вполне возможно!
Но так в "моем" запросе тоже попробуйте только одно поле выбирать из первой таблицы :-)

Код: plaintext
1.
2.
3.
4.
SELECT t1.row_id AS t1_row_id, t2.*
FROM tb1 AS t1
INNER JOIN tb1 AS t2 ON t1.row_id = t2.row_id
ORDER BY (( SUBSTR(t1.row_id,  1 ,  2 )::integer ) *  1000000  + ( SUBSTR(t1.row_id,  4 ,  8 ) :: integer)) DESC

И вы сравниваете версии с лимитом или без? У меня планировщик на подобном запросе без лимита выдает seq scan, а с лимитом index scan - тоже не маловажная разница!
...
Рейтинг: 0 / 0
интересно ...
    #34375690
Мишган-кабанчик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
SELECT t1.row_id AS t1_row_id, t2.*
FROM tb1 AS t1
INNER JOIN tb2 AS t2 ON t1.row_id = t2.row_id
ORDER BY (( SUBSTR(t1.row_id,  1 ,  2 )::integer ) *  1000000  + ( SUBSTR(t1.row_id,  4 ,  8 ) :: integer)) DESC
ваш запрос 77 секунд :) (с limit 100 - 50120 ms)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
select * from 
(
     select row_id, ( ( SUBSTR(row_id,  1 ,  2 )::integer ) *  1000000  + ( SUBSTR(row_id,  4 ,  8 ) :: integer) ) as "ex1" from tb1 k
            order by ex1
            desc
) u INNER JOIN tb1 a ON u.row_id=a.row_id
order by u.ex1 desc
мой запрос 22 секунды (с limit 100 - 500 ms ) :) Скриншоты нужны? я конечно понимаю, что запросы возвращают одинаковые наборы данных ... и в принципе-то похожи ... но мне кажется, что дело как раз в том, что у меня записи предварительно отсортированы ... я не прав? (так кажется это уже оффтоп). (мне плавать, чей запрос лучше, я просто хочу разобраться, в чем собственно дело)
...
Рейтинг: 0 / 0
интересно ...
    #34375965
Shweik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну не скрииншоты но план запроса EXPLAIN ANALYZE был бы интересен.
Да на форуме затерялся линк на отличную статью по оптимизации PostgreSQL от Sad Spirit.
...
Рейтинг: 0 / 0
интересно ...
    #34376262
Мишган-кабанчик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shweikно план запроса EXPLAIN ANALYZE был бы интересен
мой
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
Nested Loop  (cost= 8588 . 75 .. 35162 . 24  rows= 44203  width= 880 ) (actual time= 3487 . 864 .. 5158 . 565  rows= 44203  loops= 1 )
  ->  Sort  (cost= 8588 . 75 .. 8699 . 25  rows= 44203  width= 11 ) (actual time= 3457 . 646 .. 3517 . 974  rows= 44203  loops= 1 )
        Sort Key: (((substr((tb1.row_id)::text,  1 ,  2 ))::integer *  1000000 ) + (substr((tb1.row_id)::text,  4 ,  8 ))::integer)
        ->  Seq Scan on tb1 (cost= 0 . 00 .. 4268 . 07  rows= 44203  width= 11 ) (actual time= 0 . 369 .. 3337 . 844  rows= 44203  loops= 1 )
  ->  Index Scan using pi_rid on tb1 a  (cost= 0 . 00 .. 0 . 58  rows= 1  width= 864 ) (actual time= 0 . 031 .. 0 . 032  rows= 1  loops= 44203 )
        Index Cond: ((u.row_id)::text = (a.row_id)::text)"
Total runtime:  5211 . 880  ms
и не мой :)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
Sort  (cost= 57088 . 11 .. 57198 . 61  rows= 44203  width= 875 ) (actual time= 52239 . 776 .. 52371 . 560  rows= 44203  loops= 1 )
  Sort Key: (((substr((t1.row_id)::text,  1 ,  2 ))::integer *  1000000 ) + (substr((t1.row_id)::text,  4 ,  8 ))::integer)
  ->  Hash Join  (cost= 8992 . 57 .. 19223 . 43  rows= 44203  width= 875 ) (actual time= 20085 . 255 .. 49712 . 864  rows= 44203  loops= 1 )
        Hash Cond: ((t1.row_id)::text = (t2.row_id)::text)"
        ->  Seq Scan on tb1 t1  (cost= 0 . 00 .. 3605 . 03  rows= 44203  width= 11 ) (actual time= 0 . 009 .. 49 . 225  rows= 44203  loops= 1 )
        ->  Hash  (cost= 3605 . 03 .. 3605 . 03  rows= 44203  width= 864 ) (actual time= 20042 . 487 .. 20042 . 487  rows= 44203  loops= 1 )
              ->  Seq Scan on tb1 t2  (cost= 0 . 00 .. 3605 . 03  rows= 44203  width= 864 ) (actual time= 0 . 003 .. 53 . 820  rows= 44203  loops= 1 )
Total runtime:  53539 . 473  ms
запросы без limit.
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / интересно ...
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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