Thread: Re: [pgsql-ru-general] порядок вставки
Понедельник, 19 октября 2015, 17:04 +03:00 от "Dmitry E. Oboukhov" <unera@debian.org>:Дело, собственно, в том, что в таблице bc нет подрядка записей...WITH
"a" AS (
SELECT 1 AS "col"
),
"b" AS (
SELECT 2 AS "col"
),
"bc" AS (
SELECT
*
FROM
"a"
UNION ALL
SELECT
*
FROM
"b"
)
INSERT INTO "table" ("col")
SELECT
*
FROM
"bc"
;
Вопрос: есть ли гарантия того что в таблицу "table" записи вставятся
строго в том порядке в котором они в таблице "bc" или нет?
> Дело, собственно, в том, что в таблице bc нет подрядка записей... я не понял коментария как это нет? можно бесконечное множество раз делать select uinon all select и порядок выдачи будет сохраняться один и тот же. вопрос в том сохранится ли он в insert-select. -- . ''`. 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
Attachment
> я не понял коментария > как это нет? Ну вот так вот нет. > можно бесконечное множество раз делать select uinon all select и > порядок выдачи будет сохраняться один и тот же. Никто не обещает, что он будет таким же.
> вопрос в том сохранится ли он в insert-select. И, кстати, а какая, собственно, разница в каком порядке будут добавлены строки?
речь, видимо, идет о сохранении порядка sequence, create table test(id serial, val int,...)?
т.е., insert .. select, например, insert into test(val) select * from generate_series(1, 10), в test будет 1 | 1
2 | 2
2 | 2
и т.д.
в доке по INSERT про порядок ничего нет, но с какой стати он будет отличаться от результатов селекта?
вот здесь http://www.postgresql.org/docs/9.5/static/executor.html читаем:
The executor mechanism is used to evaluate all four basic SQL query types: SELECT, INSERT, UPDATE, and DELETE. For SELECT, the top-level executor code only needs to send each row returned by the query plan tree off to the client. For INSERT, each returned row is inserted into the target table specified for the INSERT.
The executor mechanism is used to evaluate all four basic SQL query types: SELECT, INSERT, UPDATE, and DELETE. For SELECT, the top-level executor code only needs to send each row returned by the query plan tree off to the client. For INSERT, each returned row is inserted into the target table specified for the INSERT.
19 октября 2015 г., 18:03 пользователь Dmitry E. Oboukhov <unera@debian.org> написал:
> Дело, собственно, в том, что в таблице bc нет подрядка записей...
я не понял коментария
как это нет?
можно бесконечное множество раз делать select uinon all select и
порядок выдачи будет сохраняться один и тот же.
вопрос в том сохранится ли он в insert-select.
--
. ''`. 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)
iEYEAREDAAYFAlYlBiUACgkQq4wAz/jiZTektACg2KteogZHONRBysweT6OgEY0G
g/wAoI51UWFqvU5UeWz6Bf3MbsndtrEP
=HghK
-----END PGP SIGNATURE-----
Re: Re[2]: [pgsql-ru-general] Re: [pgsql-ru-general] порядок вставки
From
"Dmitry E. Oboukhov"
Date:
>> вопрос в том сохранится ли он в insert-select. > И, кстати, а какая, собственно, разница в каком порядке будут добавлены строки? в таблицу записываем произошедшие одно за другим события. SERIAL в первичном ключе таким образом определяет какое событие было раньше какое позже (таймстемп тоже есть, но он больше декоративный) поэтому порядок INSERT'ов мне важен. а тут получается что в одном SQL запросе получаем два события зараз (в двух секциях WITH). и хочу сохранить их в нужном порядке -- . ''`. 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
Attachment
Re[2]: [pgsql-ru-general] Re[2]: [pgsql-ru-general] Re: [pgsql-ru-general] порядок вставки
From
Иван Фролков
Date:
> в таблицу записываем произошедшие одно за другим события. > SERIAL в первичном ключе таким образом определяет какое событие было > раньше какое позже (таймстемп тоже есть, но он больше декоративный) > поэтому порядок INSERT'ов мне важен. Вы поступаете неправильно, и вот почему - во-первых, такие вставки могут идти параллельно, и тогда порядок становится совсемуж странным; во-вторых, порядок вставки при insert действительно не определен (при каком-то другом объеме данных иположении звезд сервер может изменить план и порядок будет совсем иным); и то, что оно иногда (а то и практически всегда)может работать так, как вам надо - не более чем совпадение. Я бы набрался наглости и посоветовал бы либо сделать timestampне декоративным, либо ввести какой-то свое значение для упорядочивания).
Re: [pgsql-ru-general] Re[2]: [pgsql-ru-general] Re: [pgsql-ru-general] порядок вставки
From
Андрей Зевакин
Date:
Как насчет:
WITH
"a" AS (
SELECT 1 AS "col", 1 as part,
),
"b" AS (
SELECT 2 AS "col", 2 as part,
),
"bc" AS (
SELECT
*
FROM
"a"
UNION ALL
SELECT
*
FROM
"b"
)
INSERT INTO "table" ("col")
SELECT
comWITH
"a" AS (
SELECT 1 AS "col", 1 as part,
row_number() over () as num
),
"b" AS (
SELECT 2 AS "col", 2 as part,
row_number() over () as num
),
"bc" AS (
SELECT
*
FROM
"a"
UNION ALL
SELECT
*
FROM
"b"
)
INSERT INTO "table" ("col")
SELECT
FROM
"bc"
"bc"
order by part, num;
С уважением, Андрей Зевакин.
20 октября 2015 г., 14:22 пользователь Dmitry E. Oboukhov <unera@debian.org> написал:
>> вопрос в том сохранится ли он в insert-select.
> И, кстати, а какая, собственно, разница в каком порядке будут добавлены строки?
в таблицу записываем произошедшие одно за другим события.
SERIAL в первичном ключе таким образом определяет какое событие было
раньше какое позже (таймстемп тоже есть, но он больше декоративный)
поэтому порядок INSERT'ов мне важен.
а тут получается что в одном SQL запросе получаем два события зараз (в
двух секциях WITH). и хочу сохранить их в нужном порядке--
. ''`. 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)
iEYEAREDAAYFAlYmB74ACgkQq4wAz/jiZTeniQCguYM6XnhAOqxtRg9zC1icRmw7
+YIAnjmLepTZJ046FRW77vNYBmVFH5qv
=nGH1
-----END PGP SIGNATURE-----
> в доке по INSERT про порядок ничего нет, но с какой стати он будет отличаться > от результатов селекта? а SELECT * FROM "with_results" может отличаться в порядке? WITH "bla" AS ( SELECT .. ), "ble" AS ( SELECT .. "bla" -- тут используется "bla" и JOIN с "bla" ) INSERT .. SELECT * FROM "bla" и вот соответственно вопрос: может ли секция "ble" изменить порядок выдачи последующего SELECT из секции "bla"? если точно задачу сформулировать то получается вкратце, пишем простой биллинг-лог на входе приходит txnname и сумма sum далее табличка с логом (играем на PRIMARY KEY): id SERIAL rollback BOOLEAN NOT NULL DEFAULT FALSE sum NUMERIC(11,2) txnname TEXT прочие TIMESTAMP опускаем для краткости входим в билинг с двумя параметрами (обобщая) txnname - имя чего-то с чем связана транзакция sum - сумма билинг формирует в обычном случае такой INSERT INSERT TO "billing_log" ("rollback", "sum", "txnname") VALUES (FALSE, 10, 'заказ 342') а в случае, если по данному объекту уже была запись, то выбирает последнюю, откатывает ее и записывает новую: INSERT TO "billing_log" ("rollback", "sum", "txnname") VALUES (TRUE, -123, 'заказ 342'), (FALSE, 10, 'заказ 342') Соответственно я хочу сформировать секцию WITH, которая формирует эти (одну или две) записи, чтобы получить атомарный SQL, но возник вот этот вопрос: сохранится ли порядок записей INSERT SELECT -- . ''`. 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
Attachment
Re: Re[2]: [pgsql-ru-general] Re[2]: [pgsql-ru-general] Re: [pgsql-ru-general] порядок вставки
From
"Dmitry E. Oboukhov"
Date:
>> в таблицу записываем произошедшие одно за другим события. >> SERIAL в первичном ключе таким образом определяет какое событие было >> раньше какое позже (таймстемп тоже есть, но он больше декоративный) >> поэтому порядок INSERT'ов мне важен. > Вы поступаете неправильно, и вот почему - во-первых, такие вставки могут идти параллельно, и тогда порядок становится совсемуж странным; во-вторых, порядок вставки при insert действительно не определен (при каком-то другом объеме данных иположении звезд сервер может изменить план и порядок будет совсем иным); и то, что оно иногда (а то и практически всегда)может работать так, как вам надо - не более чем совпадение. Я бы набрался наглости и посоветовал бы либо сделать timestampне декоративным, либо ввести какой-то свое значение для упорядочивания). про параллельные вставки я все понимаю. те что идут параллельно - они (так устроена система) не предъявляют требований к тому что одна может записаться раньше другой основной поток делает один INSERT и все но вот есть конкретно случаи, когда требуется сохранить последовательность и соответственно там требуется атомарно записать две записи в БД. я в соседнем письме описал задачу более подробно -- . ''`. 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
Attachment
Re: [pgsql-ru-general] Re[2]: [pgsql-ru-general] Re[2]: [pgsql-ru-general] Re: [pgsql-ru-general] порядок вставки
From
Andrey Asyakin
Date:
а SELECT * FROM "with_results" может отличаться в порядке?
Надо бы смотреть доку по WITH.
Можно подстраховаться,
Можно подстраховаться,
with a ( select 1 n, ...),
b ( select 2 n, ...),
c ( ... union all ...)
insert into t(z, x) select z, x from c order by n
Я по другому понял вопрос, может ли в запросе insert .. select записи вставиться не в том порядке, в котором их возвращает select. Насколько я понял, нет, потому что для инсерта не создается какого то особого плана, план создается для селекта, просто вместо отправки клиенту записи пишутся в таблицу.
что то я не пойму насчет WITH, зачем он? если формируешь сам, чем не устраивает
INSERT TO "billing_log"
("rollback", "sum", "txnname")
VALUES
(TRUE, -123, 'заказ 342'),
(FALSE, 10, 'заказ 342')
INSERT TO "billing_log"
("rollback", "sum", "txnname")
VALUES
(TRUE, -123, 'заказ 342'),
(FALSE, 10, 'заказ 342')
20 октября 2015 г., 12:39 пользователь Dmitry E. Oboukhov <unera@debian.org> написал:
>> в таблицу записываем произошедшие одно за другим события.
>> SERIAL в первичном ключе таким образом определяет какое событие было
>> раньше какое позже (таймстемп тоже есть, но он больше декоративный)
>> поэтому порядок INSERT'ов мне важен.
> Вы поступаете неправильно, и вот почему - во-первых, такие вставки могут идти параллельно, и тогда порядок становится совсем уж странным; во-вторых, порядок вставки при insert действительно не определен (при каком-то другом объеме данных и положении звезд сервер может изменить план и порядок будет совсем иным); и то, что оно иногда (а то и практически всегда) может работать так, как вам надо - не более чем совпадение. Я бы набрался наглости и посоветовал бы либо сделать timestamp не декоративным, либо ввести какой-то свое значение для упорядочивания).
про параллельные вставки я все понимаю.
те что идут параллельно - они (так устроена система) не предъявляют
требований к тому что одна может записаться раньше другой
основной поток делает один INSERT и все
но вот есть конкретно случаи, когда требуется сохранить
последовательность и соответственно там требуется атомарно записать
две записи в БД.
я в соседнем письме описал задачу более подробно--
. ''`. 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)
iEYEAREDAAYFAlYmC9IACgkQq4wAz/jiZTe1ugCgxCvt2YvBgyXAjbB0CFoLNNa7
wyUAn2weG+s6/AzeDJxDSZvhCG+aEy9O
=QRLu
-----END PGP SIGNATURE-----
Re: Re: [pgsql-ru-general] Re[2]: [pgsql-ru-general] Re[2]: [pgsql-ru-general] Re: [pgsql-ru-general] порядок вставки
From
"Dmitry E. Oboukhov"
Date:
> Я по другому понял вопрос, может ли в запросе insert .. select записи > вставиться не в том порядке, в котором их возвращает select. Насколько я понял, > нет, потому что для инсерта не создается какого то особого плана, план > создается для селекта, просто вместо отправки клиенту записи пишутся в таблицу. Да вопрос именно в этом. интересно: может ли выборка секции WITH быть пересортирована в процессе выполнения другого подзапроса WITH WITH "a" AS ( SELECT .. ), "b" AS ( SELECT ... "a" ) INSERT INTO ... SELECT * FROM "a"; это первый непонятный кейз и второй может ли выборка секции WITH быть пересортирована в процессе хранения/просто выборки из нее: SELECT * FROM "a" строит же план? или всегда выберет из виртуальной таблицы в том порядке в котором выбралось? то есть в общем-то хочется понимания о том как устроено хранилище промежуточных результатов WITH: что там, plain массив или может быть например hash? > что то я не пойму насчет WITH, зачем он? если формируешь сам, чем не устраивает > INSERT TO "billing_log" > ("rollback", "sum", "txnname") > VALUES > (TRUE, -123, 'заказ 342'), > (FALSE, 10, 'заказ 342') ну тут я развернул для ясности что я хочу получить, но на практике оба значения - выборки with -- . ''`. 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
Attachment
Re: [pgsql-ru-general] Re: [pgsql-ru-general] Re[2]: [pgsql-ru-general] Re[2]: [pgsql-ru-general] Re: [pgsql-ru-general] порядок вставки
From
Andrey Asyakin
Date:
что касается второго, видимо, может. это ж обычный запрос, подчиняется общим правилам планировщика.. with, по сути, более удобная форма записи подзапросов, так что order by в итоговом селект не помешает, кажись. хотя в твоем случае на практике скорей всего все будет работать правильно и без order by.
насчет первого, опять не уверен, что понял правильно. именно вот так:
WITH "a" AS (
SELECT ..
),
"b" AS (
SELECT
...
"a"
)
INSERT INTO ... SELECT * FROM "a";
???
если да, то не повлияет. а это уже сформированный набор строк, типа временной таблицы или подзапроса, на нее не повлияет выборка из нее. b AS ( ) просто для примера? а то как то бессмысленно выглядит)
насчет первого, опять не уверен, что понял правильно. именно вот так:
WITH "a" AS (
SELECT ..
),
"b" AS (
SELECT
...
"a"
)
INSERT INTO ... SELECT * FROM "a";
???
если да, то не повлияет. а это уже сформированный набор строк, типа временной таблицы или подзапроса, на нее не повлияет выборка из нее. b AS ( ) просто для примера? а то как то бессмысленно выглядит)
ну и еще раз, на всякий, в любом случае
INSERT INTO dest SELECT * FROM source; - не важно, откуда возвращает данные SELECT, в dest они будут вставляться в том же порядке, в каком их возвращает SELECT
INSERT INTO dest SELECT * FROM source; - не важно, откуда возвращает данные SELECT, в dest они будут вставляться в том же порядке, в каком их возвращает SELECT
20 октября 2015 г., 15:45 пользователь Dmitry E. Oboukhov <unera@debian.org> написал:
> Я по другому понял вопрос, может ли в запросе insert .. select записи
> вставиться не в том порядке, в котором их возвращает select. Насколько я понял,
> нет, потому что для инсерта не создается какого то особого плана, план
> создается для селекта, просто вместо отправки клиенту записи пишутся в таблицу.
Да вопрос именно в этом.
интересно: может ли выборка секции WITH быть пересортирована в
процессе выполнения другого подзапроса WITH
WITH "a" AS (
SELECT ..
),
"b" AS (
SELECT
...
"a"
)
INSERT INTO ... SELECT * FROM "a";
это первый непонятный кейз
и второй
может ли выборка секции WITH быть пересортирована в процессе
хранения/просто выборки из нее:
SELECT * FROM "a"
строит же план? или всегда выберет из виртуальной таблицы в том
порядке в котором выбралось?
то есть в общем-то хочется понимания о том как устроено хранилище
промежуточных результатов WITH: что там, plain массив или может быть
например hash?
> что то я не пойму насчет WITH, зачем он? если формируешь сам, чем не устраивает
> INSERT TO "billing_log"
> ("rollback", "sum", "txnname")
> VALUES
> (TRUE, -123, 'заказ 342'),
> (FALSE, 10, 'заказ 342')
ну тут я развернул для ясности что я хочу получить, но на практике оба
значения - выборки with
--
. ''`. 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)
iEUEAREDAAYFAlYmN4QACgkQq4wAz/jiZTcrOwCYk+hBbI9zRBvJXRolXvTJ6n4q
/wCgmPf7oZOHDoHRJpfHQGjrv0SUNpg=
=GkFE
-----END PGP SIGNATURE-----