Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
вычесть множества
|
|||
|---|---|---|---|
|
#18+
Помогите плиз ускорить запрос ! есть две таблицы: CREATE TABLE a(id INT NOT NULL, PRIMARY KEY(id)); CREATE TABLE b(id INT NOT NULL, PRIMARY KEY(id)); таблица a содержит множество числел (скажем 2.5 миллиона уникальных идетификаторов), таблица b содержит те-же числа либо какие-то из них отсутствуют. кто нибудь может предложить вариант как увидеть числа которые есть в таблице a но нету в таблице b иначе как таким запросом: SELECT * FROM a LEFT OUTER JOIN b ON (a.id = b.id) WHERE b.id IS NULL; EXCEPT то-же пробывал - работает еще медленней чем LEFT JOIN может есть что-нибудь турбированное postgreSQL специфичное ??? слить в одну таблицы нельзя потому как на самом деле в реальности в таблице b есть еще один ключ который участвует в выборке. пробывал создавать таблицу b как CREATE TABLE c(id INT NOT NULL, PRIMARY KEY(id), FOREIGN KEY(id) REFERENCES a(id)); и как CREATE TABLE d(id INT NOT NULL, FOREIGN KEY(id) REFERENCES a(id)); по идее FOREIGN KEY долен указывать оптимизатору что ключи то один и общие и существенно ускорять запрос а в реальности это наоборот все замедляет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.04.2008, 17:22 |
|
||
|
вычесть множества
|
|||
|---|---|---|---|
|
#18+
xtronПомогите плиз ускорить запрос ! есть две таблицы: CREATE TABLE a(id INT NOT NULL, PRIMARY KEY(id)); CREATE TABLE b(id INT NOT NULL, PRIMARY KEY(id)); таблица a содержит множество числел (скажем 2.5 миллиона уникальных идетификаторов), таблица b содержит те-же числа либо какие-то из них отсутствуют. кто нибудь может предложить вариант как увидеть числа которые есть в таблице a но нету в таблице b иначе как таким запросом: SELECT * FROM a LEFT OUTER JOIN b ON (a.id = b.id) WHERE b.id IS NULL; EXCEPT то-же пробывал - работает еще медленней чем LEFT JOIN может есть что-нибудь турбированное postgreSQL специфичное ??? слить в одну таблицы нельзя потому как на самом деле в реальности в таблице b есть еще один ключ который участвует в выборке. пробывал создавать таблицу b как CREATE TABLE c(id INT NOT NULL, PRIMARY KEY(id), FOREIGN KEY(id) REFERENCES a(id)); и как CREATE TABLE d(id INT NOT NULL, FOREIGN KEY(id) REFERENCES a(id)); по идее FOREIGN KEY долен указывать оптимизатору что ключи то один и общие и существенно ускорять запрос а в реальности это наоборот все замедляет. Надо бы на планы и времена посмотреть, а то напишут медленно, вот и думай, что он имел ввиду. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.04.2008, 19:19 |
|
||
|
вычесть множества
|
|||
|---|---|---|---|
|
#18+
Oleg BartunovНадо бы на планы и времена посмотреть, а то напишут медленно, вот и думай, что он имел ввиду. Ok. В таблицах a,b,c,d аюсолюно одинаковые данные - 2500000 уникальных ключей. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.04.2008, 01:50 |
|
||
|
вычесть множества
|
|||
|---|---|---|---|
|
#18+
xtron пишет: > кто нибудь может предложить вариант как увидеть числа которые есть в > таблице a но нету в таблице b иначе как таким запросом: > SELECT * FROM a LEFT OUTER JOIN b ON (a.id = b.id) WHERE b.id IS NULL; select * from a where not exists ( select * from b where b.id = a.id ) или select * from a where a.id not in ( select b.id from b ) что почти одно и то же. > EXCEPT то-же пробывал - работает еще медленней чем LEFT JOIN > может есть что-нибудь турбированное postgreSQL специфичное ??? Вычитание множеств - по жизни сложная операция и небыстрая. O(N*M) N,M - мощности множеств. Если у вас будет индек на id (а он есть), то - O(N*log(M)), но не быстрее. Хотя нет, есть еще sort merge join, O(max(N*M)), но не знаю, поддерживает ли его PG. > пробывал создавать таблицу b как > CREATE TABLE c(id INT NOT NULL, PRIMARY KEY(id), FOREIGN KEY(id) > REFERENCES a(id)); > и как > CREATE TABLE d(id INT NOT NULL, FOREIGN KEY(id) REFERENCES a(id)); > по идее FOREIGN KEY долен указывать оптимизатору что ключи то один и > общие и существенно ускорять запрос а в реальности это наоборот все > замедляет. Ничего это не замедляет (замедляться будут только модификации), но и ускорять не должно. FOREIGN KEY оптимизатору до фени. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.04.2008, 13:49 |
|
||
|
вычесть множества
|
|||
|---|---|---|---|
|
#18+
xtron, по моему опыту, длинные, кривые или медленные запросы возникают при плохо поставленной или плохо решенной задаче. Вы бы рассказали, зачем вам вычитание и насколько велика таблица b. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.04.2008, 16:20 |
|
||
|
вычесть множества
|
|||
|---|---|---|---|
|
#18+
PostreSQL начинающийxtron, по моему опыту, длинные, кривые или медленные запросы возникают при плохо поставленной или плохо решенной задаче. Вы бы рассказали, зачем вам вычитание и насколько велика таблица b. Задача простая: в первой таблице события который нужно раздать клиентам, а во второй отметки клиентов о том что они событие получили. получать они должны только новые события отсюда вычитание. величина второй таблицы это величина первой помноженная на количество клиентов. в чем тут кривизна ??? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2008, 02:53 |
|
||
|
вычесть множества
|
|||
|---|---|---|---|
|
#18+
MasterZivВычитание множеств - по жизни сложная операция и небыстрая. Кстати по моим тестам что SELECT count(*) FROM a LEFT OUTER JOIN b ON (a.id = b.id) WHERE b.id IS NULL; что SELECT count(*) FROM a, b WHERE a.id = b.id; те что вычитание что сложение выполняются в PostgreSQL одинаковое время на разных количествах записей (проверял на 2.5 и 10 миллионах) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2008, 03:14 |
|
||
|
вычесть множества
|
|||
|---|---|---|---|
|
#18+
xtronчто вычитание что сложение выполняются в PostgreSQL одинаковое время обе таблицы заполнены, в случае если во второй меньше записей то сложение быстрее ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2008, 04:21 |
|
||
|
вычесть множества
|
|||
|---|---|---|---|
|
#18+
> получать они должны только новые события отсюда вычитание Логику раздачи опишите. Какие-то атрибуты (время получения, например) из второй таблицы используются или просто регистрируется факт? > величина второй таблицы это величина первой помноженная на количество клиентов. в чем тут кривизна??? Я не могу придумать задачу, которая требовала бы такой реализации. Произведение - вот это и есть криво. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2008, 10:41 |
|
||
|
вычесть множества
|
|||
|---|---|---|---|
|
#18+
Ну вот пример на вычитание. Есть внешняя система А, которая вообще не факт что RDBMS или её трогать нельзя. (Пример Active Directory). Есть некий момент времени, когда пользователь заново хочет закачать эти данные в систему. При этом в изначальной системе с ними могло происходить практически всё что угодно. Соответсвенно нужно найти разницу и с ней что-то согласно бизнес-логики сделать (пример - внести заново отношения подразделений из AD в мою БД, обновить имена и атрибуты пользователей). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2008, 11:28 |
|
||
|
вычесть множества
|
|||
|---|---|---|---|
|
#18+
> Есть некий момент времени, когда пользователь заново хочет закачать эти данные в систему Где здесь произведение? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2008, 12:12 |
|
||
|
вычесть множества
|
|||
|---|---|---|---|
|
#18+
PostreSQL начинающий> Есть некий момент времени, когда пользователь заново хочет закачать эти данные в систему Где здесь произведение? А я и не говорил, что это пример на умножение. Это на вычитание точнее на исключающую разность, но это ИМХо ньюансы реализации. Вы чуть раньше спрашивали про вычитание. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2008, 13:02 |
|
||
|
вычесть множества
|
|||
|---|---|---|---|
|
#18+
Andrey Daeron, извините, неправильно понял пример. Да, вы правы. Автору вопроса я бы предложил сначала подумать о простых ограничениях: трудно представить, чтобы всегда требовались все данные, скорее всего, значительную часть можно держать в архиве. Если действительно необходим лог персональной регистрации получения, есть смысл также оптимизировать лог доставки (таблица b), разделив его на несколько частей в зависимости от поведения подписчиков. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2008, 13:51 |
|
||
|
вычесть множества
|
|||
|---|---|---|---|
|
#18+
PostreSQL начинающийAndrey Daeron, извините, неправильно понял пример. Да, вы правы. Автору вопроса я бы предложил сначала подумать о простых ограничениях: трудно представить, чтобы всегда требовались все данные, скорее всего, значительную часть можно держать в архиве. Если действительно необходим лог персональной регистрации получения, есть смысл также оптимизировать лог доставки (таблица b), разделив его на несколько частей в зависимости от поведения подписчиков. Требуются ВСЕ данные. Ограничение по времени тут не ввести. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2008, 15:56 |
|
||
|
вычесть множества
|
|||
|---|---|---|---|
|
#18+
xtron PostreSQL начинающийAndrey Daeron, извините, неправильно понял пример. Да, вы правы. Автору вопроса я бы предложил сначала подумать о простых ограничениях: трудно представить, чтобы всегда требовались все данные, скорее всего, значительную часть можно держать в архиве. Если действительно необходим лог персональной регистрации получения, есть смысл также оптимизировать лог доставки (таблица b), разделив его на несколько частей в зависимости от поведения подписчиков. Требуются ВСЕ данные. Ограничение по времени тут не ввести. Бррр. Может я как-то невнимательно прочитал или понял постановку. Есть события, которые происходят (таблица А). Есть клиенты (таблица Б). Это две разные таблицы. Есть таблица с данными, которые просто являются перемножением этих двух таблиц (таблица В). И в этой таблице отмечаются события полученные/отправленные пользователю? Т.е. в таблице В всегда А*Б записей? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2008, 16:11 |
|
||
|
вычесть множества
|
|||
|---|---|---|---|
|
#18+
Че-то рука дрогнула. При такой организации (поддерживается триггерами, невелика проблема) вычитаний вроде не нужно простой индексированный SELECT по таблице. Накладные расходы по организации - тоже невелики. Тока филфактор нужно в 40-50% выставить что бы UPDATE быстрее бегали. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2008, 16:15 |
|
||
|
вычесть множества
|
|||
|---|---|---|---|
|
#18+
Andrey Daeron Бррр. Может я как-то невнимательно прочитал или понял постановку. Есть события, которые происходят (таблица А). Есть клиенты (таблица Б). Это две разные таблицы. Есть таблица с данными, которые просто являются перемножением этих двух таблиц (таблица В). И в этой таблице отмечаются события полученные/отправленные пользователю? Т.е. в таблице В всегда А*Б записей? Нет. Есть таблица A - там события. И есть таблица B там отметки от получении событий клиентами. Больше таблиц нет все что я там выше привел это пыпытки ускорить выборку не полученных клиентами событий. Дело в том что клиент может отказаться от события даже старого а выбирать нужно все не полученные клиентами события поэтому ограничение по времени ввести нельзя. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2008, 16:19 |
|
||
|
вычесть множества
|
|||
|---|---|---|---|
|
#18+
xtron Andrey Daeron Бррр. Может я как-то невнимательно прочитал или понял постановку. Есть события, которые происходят (таблица А). Есть клиенты (таблица Б). Это две разные таблицы. Есть таблица с данными, которые просто являются перемножением этих двух таблиц (таблица В). И в этой таблице отмечаются события полученные/отправленные пользователю? Т.е. в таблице В всегда А*Б записей? Нет. Есть таблица A - там события. И есть таблица B там отметки от получении событий клиентами. Больше таблиц нет все что я там выше привел это пыпытки ускорить выборку не полученных клиентами событий. Дело в том что клиент может отказаться от события даже старого а выбирать нужно все не полученные клиентами события поэтому ограничение по времени ввести нельзя. 1. Т.е. таблицы клиентов нет? Как-то странно, и не логично - клиенты есть таблицы с нимим нет 2. То, что нарисовал я - это предложение уйти от динамического формирования умножения таблиц, в сторону его статической реализации. Благо - всё равно отметки ставить нужно. Не хочет клиент его видеть ваще - пожалуйста или удаляем запись из этой таблицы, либо ставим признак - клиент забил на событие. У меня такая схема в рассылках сделана. Одно и то же сообщение могут получать люди и отделы, есть подвтерждение о получении, отказ от получения, забивание... статическая таблицка формируется быстро (по сути - куча инсертов или по количеству клиентов, либо по количеству сообщений), а удобств много. В частности быстрая аналитика в любом разрезе, возможность введения дополнительных признакофф. Надеюсь занимаемое место Вас не беспокоит :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2008, 16:29 |
|
||
|
вычесть множества
|
|||
|---|---|---|---|
|
#18+
Andrey Daeron 1. Т.е. таблицы клиентов нет? Как-то странно, и не логично - клиенты есть таблицы с нимим нет Смотрите есть таблица А: CREATE TABLE a(id INT NOT NULL, PRIMARY KEY(id), info text); те события скажем (1, 'первое событие'), (2, 'второе событие') и есть таблица B: CREATE TABLE b(id INT NOT NULL, PRIMARY KEY(id), client_id INT NOT NULL); те отметки о получении клиентами событий скажем: (1, 1), (2, 1), (2, 2) - те первый клиент получил 1 и 2 события, а второй клиент только второе событие. Нужно быстро выбрать НЕ полученные клинетом события ! те SELECT * FROM a LEFT OUTER JOIN b ON (a.id = b.id) WHERE b.id IS NULL AND d.client_id = 2; Andrey Daeron 2. То, что нарисовал я - это предложение уйти от динамического формирования умножения таблиц, в сторону его статической реализации. Благо - всё равно отметки ставить нужно. Не хочет клиент его видеть ваще - пожалуйста или удаляем запись из этой таблицы, либо ставим признак - клиент забил на событие. У меня такая схема в рассылках сделана. Одно и то же сообщение могут получать люди и отделы, есть подвтерждение о получении, отказ от получения, забивание... статическая таблицка формируется быстро (по сути - куча инсертов или по количеству клиентов, либо по количеству сообщений), а удобств много. В частности быстрая аналитика в любом разрезе, возможность введения дополнительных признакофф. Надеюсь занимаемое место Вас не беспокоит :) Может я чего то не понимаю... Объясните как я по шагам вашу мысль плиз ! Место не совершенно не беспокоит. Беспокоит только скорость получения не полученных конкретным клиентом событий. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2008, 16:40 |
|
||
|
вычесть множества
|
|||
|---|---|---|---|
|
#18+
xtron Может я чего то не понимаю... Объясните как я по шагам вашу мысль плиз ! Место не совершенно не беспокоит. Беспокоит только скорость получения не полученных конкретным клиентом событий. Попробую. Table A: CREATE TABLE messages(id serial, msg text) Table B: CREATE TABLE clients(id serial, name text) Table C: CREATE TABLE cl_mesg(id serial, client_id integer, message_id integer, is_obtain integer, is_obstructed integer, time_reciving timestamp, time_read timestamp); Индексы уникальности - по вкусу/задаче. Triggers on A (messages): 1. On Insert (добавление для всех клиентов этого сообщения. Можно вводить критерии, может мёртвым клиентам уже они не нужны, может еще кому не нужны): INSERT INTO cl_mesg (client_id,message_id) SELECT id, new.id (это будет ID message) FROM clients; 2. On update (по идее нафиг не нужно, но если меняем что-то в сообщении, то может нужно перпослать): INSERT INTO cl_mesg (client_id,message_id) SELECT id, new.message_id FROM clients; 3. On delete (прибить все сообщения, вне зависимости от того прочитаны или нет) по идее тут FK должны отреботать каскадно. Triggers on B (clients) - аналогично, только со стороны сообщений. Клиент - берётся как new.id Для таблицы cl_mesg - будет прикольно попробовать поиграться с fillfactor, что бы обновления на то, что клиент получил событие проходили быстрее. Тогда Ваш запрос- "а кто еще не получил что-то", это просто SELECT id FROM cl_mesg WHERE is_reciev IS NULL; ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2008, 17:02 |
|
||
|
вычесть множества
|
|||
|---|---|---|---|
|
#18+
> Есть таблица A - там события. И есть таблица B там отметки от получении событий клиентами. Вы написали это в первом сообщении, это понятно. У вас три задачи: первая - отдать новые сообщения всем пользователям, вторая - хранить лог получений, третья - дать возможность пользователям изменять статус соообщений (почему это нужно - для меня загадка: если пользователь получил сообщение, то не очень понятно, как он может от него отказаться и зачем ему второй (третий, четвертый и т. д.) раз предлагать то же самое сообщение; ну, да ладно, это не важно). Зачем держать вместе лог полученных сообщений и не полученных, если отдавать нужно только не полученные, а менять статус можно только у полученных? А вообще странная задача, как я уже сказал. Я по-прежнему не могу придумать ничего похожего в реальной жизни. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2008, 17:26 |
|
||
|
вычесть множества
|
|||
|---|---|---|---|
|
#18+
Andrey DaeronТогда Ваш запрос- "а кто еще не получил что-то", это просто SELECT id FROM cl_mesg WHERE is_reciev IS NULL; те вы предлагаете при возникновении события генерировать для всех клиентов отметки об этом событии, а при получении клиентом события помечать его как полученное ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2008, 17:33 |
|
||
|
вычесть множества
|
|||
|---|---|---|---|
|
#18+
PostreSQL начинающийне очень понятно, как он может от него отказаться Может. PostreSQL начинающий Зачем держать вместе лог полученных сообщений и не полученных, если отдавать нужно только не полученные, а менять статус можно только у полученных? В таблице B храняться ТОЛЬКО полученные сообщения. Отказ от сообщения - удаление строки с пометкой получения сообщения. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2008, 17:36 |
|
||
|
вычесть множества
|
|||
|---|---|---|---|
|
#18+
> В таблице B храняться ТОЛЬКО полученные сообщения. Ну и зачем вы пишите, что содержимое таблицы - это произведение? Других решений у этой задачи, отличных от уже приведенных, нет. А задача все-таки кривая. Ну не бывает так, чтобы сообщения только добавлялись и всегда одномоментно были нужны все сразу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2008, 18:02 |
|
||
|
вычесть множества
|
|||
|---|---|---|---|
|
#18+
xtron Andrey DaeronТогда Ваш запрос- "а кто еще не получил что-то", это просто SELECT id FROM cl_mesg WHERE is_reciev IS NULL; те вы предлагаете при возникновении события генерировать для всех клиентов отметки об этом событии, а при получении клиентом события помечать его как полученное ? Да. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2008, 18:08 |
|
||
|
|

start [/forum/topic.php?fid=53&msg=35261818&tid=2004424]: |
0ms |
get settings: |
7ms |
get forum list: |
9ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
13ms |
get topic data: |
6ms |
get forum data: |
1ms |
get page messages: |
40ms |
get tp. blocked users: |
1ms |
| others: | 237ms |
| total: | 318ms |

| 0 / 0 |
