|
Селект с фильтром,который выдаст только те записи котороые удовлетворяют условию
|
|||
---|---|---|---|
#18+
booby, Производительность в варианте с multiple exists перво на перво будет зависеть от селективности САМОГО селективного фильтра в наборе. Т.е. если условно у вас в условии на channel_type 'SMS' ,'PUSH', 'доставка голубями' и с 'SMS' ,'PUSH' по 10 миллионов строк а с 'доставка голубями' всего 10 строк то вариант с exists выйграет у любого мыслимого альтернативного варианта просто потому что он начнет с semijoin от exists (select from person_channel pc where p.id = pc.person_id and pc.channel_type= 'доставка голубями' ) и далее быстро проверит найденные 10 строк по остальным 2м exits. Все остальные варианты будут так или иначе скатываться с полным переборам таблицы person а зачастую и таблицы person_channel с соответствующей печальной производителностью. Если же у вас там 10 низкоселективных channel_type в условии - там надо думать как лучше и сравнивать на конкретных реальных или синтетических данных. -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2021, 10:31 |
|
Селект с фильтром,который выдаст только те записи котороые удовлетворяют условию
|
|||
---|---|---|---|
#18+
Maxim Boguk, Не думаю. То, что вы описываете, видится как комбинация джойна с фильтром, при которой какие-то exists уедут в семиджойн, а какие-то останутся в фильтрах. Допустим, что целевой построитель плана выполнения запроса достаточно умен, чтобы именно так и работать на релевантной статистике. Тогда та часть, которая останется в фильтрах отработает за разумное время только при наличии структур типа bitmap-индексов. (И, если они есть, то есть смысл вообще все оставить в фильтре) Иначе кролик сдохнет под тяжестью множественных лукапов. Принципиальный момент в такого рода задаче - по постановке всяко требуется полный просмотр person_channel, то есть фильтрация не снижает совсем, или не снижает сильно объём просматриваемых данных, даже при пробеге по bitmap-индексу. В этих обстоятельствах безфильтровый полный пробег по person_channel с группировкой и агрегацией вполне смотрится. И тем лучше, чем больше сама person_channel и список обязательных требований. Мне кажется вполне разумным ожидать, что рано или поздно он опередит вариант с exists. А при отсутствии bitmap-индексов - опередит несомненно, и на достаточно малых значениях длинах списка требований (пусть будет - ~7-8 ). Другой вопрос, что в варианте с группировкой кажется предпочтительным вместо ( Count(*) from таблица_требований ) иметь групповую функцию, дающую слепок группы требований, с которым непосредственно можно было бы сравнивать слепок списка каналов конкретного person_id. Для нумерованных списков длиной <= 64 можно было использовать bit_and, благо, он есть в postgress. Преимущество Count в том, что он сработает стандартно на любых объёмах, без изобретения дополнительных конструкций для поддержки списков требований большего размера. PS Думаю, что в случае использования технологий того рода, что в oracle называют "exadata" - с фильтрацией на диске, блочными индексами и прочими чудесами, даже bitmap-индексам не стоит начинать соревноваться с простым и незатейливым полным просмотром. имхо. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2021, 11:33 |
|
Селект с фильтром,который выдаст только те записи котороые удовлетворяют условию
|
|||
---|---|---|---|
#18+
booby, в паралельной теме мне предложили создать функциию ,которая будет создавать в памяти сессии временную таблицу с типами каналов Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15.
Надо логику запроса поправить ,учитывая наличие временной таблицы,если конечно такой вариант вообще имеет место быть ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2021, 11:42 |
|
Селект с фильтром,который выдаст только те записи котороые удовлетворяют условию
|
|||
---|---|---|---|
#18+
с временной таблицей вы можете использовать любую из работоспособных ранее показанных логик в обоих ветка. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2021, 11:45 |
|
Селект с фильтром,который выдаст только те записи котороые удовлетворяют условию
|
|||
---|---|---|---|
#18+
booby с временной таблицей вы можете использовать любую из работоспособных ранее показанных логик в обоих ветка. а какой запрос в таком случае будет работать с временной таблицей- я честно не достаточно силен в такого рода запросах если не сложно покажите рабочий пример . ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2021, 11:51 |
|
Селект с фильтром,который выдаст только те записи котороые удовлетворяют условию
|
|||
---|---|---|---|
#18+
booby, "Принципиальный момент в такого рода задаче - по постановке всяко требуется полный просмотр person_channel," - с чего вы это взяли? Задача решения с exists именно избежать полного просмотра. -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2021, 12:26 |
|
Селект с фильтром,который выдаст только те записи котороые удовлетворяют условию
|
|||
---|---|---|---|
#18+
booby, Для закрытия вопроса - вот полный test case про то как оно в реальности работает Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39.
А теперь тест: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26.
И никаких полных переборов person_channel как и ожидалось. "Допустим, что целевой построитель плана выполнения запроса достаточно умен, чтобы именно так и работать на релевантной статистике." - таки это базовая его функциональность - решать как такие вещи лучше делать. Учите матчасть и проверяйте свои теории на тестовых данных перед тем как советовать. PS: и даже в случае отсутствия селективного фильтра в наборе - продолжает работать неплохо и без seq scan по person_channel Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33.
... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2021, 12:56 |
|
Селект с фильтром,который выдаст только те записи котороые удовлетворяют условию
|
|||
---|---|---|---|
#18+
Maxim Boguk, Не подскажите а как будет выглядеть вариант запроса ,если я запишу типы каналов в временную таблицу ?заранее спасибо ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2021, 13:08 |
|
Селект с фильтром,который выдаст только те записи котороые удовлетворяют условию
|
|||
---|---|---|---|
#18+
asv79, Я бы не стал... временные таблицы в PG очень дорогое удовольствие и на вашей задаче они выйгрыша не дадут вообще ни в каком варианте (тем более если запрос предполагается вызывать часто). Советы про временные таблицы обычно идут от старых оракловодов где это могло помогать временами. Сам факт что появляется слово distinct - уже убивает любую надежду на разумную производительность. Тогда уж вместо временной таблицы конструктор values или unnest использовать (но выйгрыша это не даст). PS: в 99% случаев подобных задач если в вашем решении появилось слово distinct - вы что то сильно не то делаете. -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2021, 13:13 |
|
Селект с фильтром,который выдаст только те записи котороые удовлетворяют условию
|
|||
---|---|---|---|
#18+
Maxim Boguk, Спасибо .Применил ваш вариант первоначальный ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2021, 13:24 |
|
Селект с фильтром,который выдаст только те записи котороые удовлетворяют условию
|
|||
---|---|---|---|
#18+
Maxim Boguk, Признаю, это не было умной идеей - свой пост мне оформлять в виде обращения к вам. Хотя я мог бы догадаться об этом по стилю вашей подписи. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2021, 13:35 |
|
Селект с фильтром,который выдаст только те записи котороые удовлетворяют условию
|
|||
---|---|---|---|
#18+
PetroNotC Sharp asv79, Пятый вариант триггер поставить и перечень SMS,EMAIL....etc' будет всегда автоматом в табле person Смотря что по бизнесу надо. OLAP/OLTP Хороший вариант. Но я-бы обсудил различные сценарии обратных (компенсирующих) DML когда мы например удаляем "SMS" из дочерней таблицы. И возможную легкую денормализацию родительской таблички. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2021, 16:01 |
|
Селект с фильтром,который выдаст только те записи котороые удовлетворяют условию
|
|||
---|---|---|---|
#18+
mayton, Конечно. Делал такое и была функция генерируйВьюху() А она вызывалась по триггеру на события как вставки так и удаления. То есть мы меняли схему бд. Но можно менять и нормализацию. Мы генерим идеи, а выбирает архитектор по многим факторам. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2021, 19:14 |
|
Селект с фильтром,который выдаст только те записи котороые удовлетворяют условию
|
|||
---|---|---|---|
#18+
Maxim Boguk, +1 про distinct Не люблю его) ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2021, 19:20 |
|
Селект с фильтром,который выдаст только те записи котороые удовлетворяют условию
|
|||
---|---|---|---|
#18+
PetroNotC Sharp mayton, Конечно. Делал такое и была функция генерируйВьюху() А она вызывалась по триггеру на события как вставки так и удаления. То есть мы меняли схему бд. Но можно менять и нормализацию. Мы генерим идеи, а выбирает архитектор по многим факторам. Я вот щас еще раз сравнил реализацию materialized views в Оракле и в PG. В последнем - тухляк. Не поддерживаются fast-режимы. Это когда мы обновляем не весь mview а отслеживаем только изменённые data-rows по журналам. Всему импортозамещению я сочувствую. PG - конешно опенсорсный. Но блин... это-же сколько тонн человеко-часов надо потратить чтобы взять PG и впилить в него фичу (реально классную фичу) из Оракла. Мне-бы до конца жизни хватило сидеть и разбираться в исходниках постгреса. Увлекательное занятие было-бы на пенсии. Мдя. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2021, 19:29 |
|
Селект с фильтром,который выдаст только те записи котороые удовлетворяют условию
|
|||
---|---|---|---|
#18+
PetroNotC Sharp Maxim Boguk, +1 про distinct Не люблю его) В тех специальных условиях, которые для себя сформулировал Максим, путём определения уникального индекса, никакого distinct технически не требуется. В данном конкретном случае существо дела совершенно в другом. 2mayton содержательный oracle-проект не только на db2, но даже на tibero db весьма непросто перенести. А перенести в postgress, для проекта сложностью в три - пять сотен человеко-лет, это примерно как человечеству переселиться, если не в соседнюю галактику, то, как минимум, на спутники Сатурна или Юпитера. При том, что круг идей и совокупность алгоритмов у любых разумно построенных субд совпадает на 95-98% Оставшиеся пара-тройка процентов образуют непреодолимую пропасть. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2021, 21:02 |
|
Селект с фильтром,который выдаст только те записи котороые удовлетворяют условию
|
|||
---|---|---|---|
#18+
Господа. Правильно я понял что сабж относится к области: - вхождение множества А в множество Б. Или термин выше относится к варианту с временной таблицей? Например такой вариант составил Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31.
... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2021, 21:49 |
|
Селект с фильтром,который выдаст только те записи котороые удовлетворяют условию
|
|||
---|---|---|---|
#18+
PetroNotC Sharp Господа. Правильно я понял что сабж относится к области: - вхождение множества А в множество Б. ммм. не то, чтобы совсем не так, но, в целом - нет. Пусть Б- обязательное множество экзаменов, при сдаче которых студент из А-множетсва результатов сдачи экзаменов, переводится на следующий курс. (Здесь предполагается, что "двойки" в A не пишутся - если двойка, у студента просто нет записи в результатах экзаменов А) варианты задачи: 1) Требуется отобрать для перевода на следующий курс всех таких студентов, которые сдали не менее, чем множество обязательных экзаменов (требований). Если кроме обязательных сдали какие-то еще - то такие годятся, их тоже, несомненно переведут на следующий курс. Это обычное реляционное деление А на Б, с допустимым "остатком" 2) Отыскиваются только те, кто сдал набор экзаменов, точно равный указанному с множестве Б - не меньше, но и не больше. Это называют точным реляционным делением. Например, это претенденты на обычную стипендию. В них нехорошо помещать тех, кто сдал экзаменов больше обязательного списка. Таких надо в претенденты на повышенную стипендию определять. То есть это задача на отбор персон, соответствующих квалификационным требованиям. Если сказано в наборе обязательных требований к квалификации кандидата автор Java 11, Kotlin, Spring Boot, WebFlux, R2DBC и прочее; • legacy: Java 8, Groovy, Spring, Hibernate, ActiveMQ; • Git, Gitlab, Gitlab-CI; • Docker и Kubernetes; • JIRA, Confluence, Agile Scrum; • Quality gate: code coverage + vulnerabilities + maintainability. И хотя бы одного слова в резюме не встречается (например - "прочее"), то кандидат в любом случае на собеседование не вызывается. А если есть лишние слова - Fortran, Ada, C++, Julia, Oracle, Postgress, MySql, то человек вызывается на собеседование, если "остаток от деления" допускается, и не вызывается, если выполняется точное деление, "без остатка". ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2021, 22:19 |
|
Селект с фильтром,который выдаст только те записи котороые удовлетворяют условию
|
|||
---|---|---|---|
#18+
booby, Уникальный индекс в моём решении не требуется и никак на его эффект и скорость работы не влияет. PS: в контексте задачи обычно если мы о реляционном делении говорим обычно студент не может иметь два одинаковых сданных экзамена поэтому uniq обычно предполагается. Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22.
Код: sql 1. 2. 3. 4. 5.
Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22.
Альтернативное решение которое действительно может быть быстрее если много низкоселективных условий будет иметь вид: SELECT * from person p where p.id IN (SELECT person_id FROM person_channel WHERE channel_type IN ('SMS', 'PUSH', 'POSTAL DOVE') GROUP BY person_id HAVING count(distinct channel_type)>=3); которое будет иметь константное более менее время работы вне зависимости от селективности набора channel_type Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20.
Что проигрывает в 30 раз версии с exists НА СЕЛЕКТИВНОМ ФИЛЬТРЕ. Если же фильтр не селективен то получаем сравнимое время работы: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49.
В итоге еще раз подтверждается правило что надо тестировать тестировать и еще раз тестировать разные варианты как минимум на синтетике а в идеале на копии реальных данных и главное реальных запросов и фильтров (понимая распределения этих фильтов в production). -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
21.06.2021, 00:05 |
|
Селект с фильтром,который выдаст только те записи котороые удовлетворяют условию
|
|||
---|---|---|---|
#18+
mayton PetroNotC Sharp mayton, Конечно. Делал такое и была функция генерируйВьюху() А она вызывалась по триггеру на события как вставки так и удаления. То есть мы меняли схему бд. Но можно менять и нормализацию. Мы генерим идеи, а выбирает архитектор по многим факторам. Я вот щас еще раз сравнил реализацию materialized views в Оракле и в PG. В последнем - тухляк. Не поддерживаются fast-режимы. Это когда мы обновляем не весь mview а отслеживаем только изменённые data-rows по журналам. Всему импортозамещению я сочувствую. PG - конешно опенсорсный. Но блин... это-же сколько тонн человеко-часов надо потратить чтобы взять PG и впилить в него фичу (реально классную фичу) из Оракла. Мне-бы до конца жизни хватило сидеть и разбираться в исходниках постгреса. Увлекательное занятие было-бы на пенсии. Мдя. Практика показала что если мы переносим сколь угодно большой ВЕБ проект (а я переносил как минимум один из топовых сайтов рунета с mysql на postgres в одни руки) - это не так уж сложно и вполне поддается решению за разумное время. Совсем другое дело когда надо перенести какой то биллинг или АБС с миллионами строк хранимок и (mat)views - там сложность переноса в том что там нарушена изоляция данных от кода и фактически мы не базу с данными и формализованным языком SQL переносим а переносим весь проект с языка А (хранимки ORACLE) на язык Б (хранимки postgresql) - и тут обьем работ конечно очень большой (хотя учитывая цену лицензии на оракел часто оправданный... не всегда конечно). Это как с С++ на Java переписать... вроде и похоже но автоматических трансляторов рабочих не существует. -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
21.06.2021, 00:12 |
|
Селект с фильтром,который выдаст только те записи котороые удовлетворяют условию
|
|||
---|---|---|---|
#18+
Интересная эта штука.... partial indexes. Вот попробовал. Но нужны реальные вероятности и взаимовязи предикатов SMS/Push/Email. На синтетике - не те ощущения. Вобщем пускай Стасик проверяет если хочет. И триггер надо добавить. Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67.
... |
|||
:
Нравится:
Не нравится:
|
|||
21.06.2021, 00:20 |
|
Селект с фильтром,который выдаст только те записи котороые удовлетворяют условию
|
|||
---|---|---|---|
#18+
Maxim Boguk booby, Уникальный индекс в моём решении не требуется и никак на его эффект и скорость работы не влияет. ... вот что вы говорили: Maxim BogukСам факт что появляется слово distinct - уже убивает любую надежду на разумную производительность. Так вот, неизбежно distinct появляется только в варианте запроса с группировкой с последующим фильтром вида Код: sql 1.
когда пара (A.person_id, A.subject) неуникальна. И, если такая пара ограничена уникальностью, то это единственное обязательное вхождение distinct автоматически исчезает. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.06.2021, 00:32 |
|
Селект с фильтром,который выдаст только те записи котороые удовлетворяют условию
|
|||
---|---|---|---|
#18+
хм. на миллионе записей: Код: sql 1. 2. 3. 4. 5.
а на двух миллионах: Код: sql 1. 2. 3. 4. 5.
Как оперативка у бобика сдохла для построения битмап-карты, так сразу и Group By заиграл, негромкой дудочкой. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.06.2021, 01:00 |
|
Селект с фильтром,который выдаст только те записи котороые удовлетворяют условию
|
|||
---|---|---|---|
#18+
booby, Не, ну у нас то задача определена и вариант только один. Множество детей у мастера А должно обязательно содержать множество Б называемых автором фильтры. Поэтому и спросил как это одной фразой назвать. Так как оператор in проверяет вхождение одного элемента. А оператор EXCEPT то что надо но вроде только от постгри. Решение выше вообще вроде работает. Возможно это называется как вы написали Это обычное реляционное деление А на Б, с допустимым "остатком". ОК. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.06.2021, 07:11 |
|
Селект с фильтром,который выдаст только те записи котороые удовлетворяют условию
|
|||
---|---|---|---|
#18+
booby, Разница в том что в первом плане есть uniq индекс а во втором нет. Поэтому в первом плане не требуется стадия убирания дубликатов строк. Да и по скорости они не отличаются почти. 32MB work_mem достаточно на очень дофига bitmap scan строк. -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
21.06.2021, 10:07 |
|
|
start [/forum/topic.php?fid=53&msg=40078957&tid=1993940]: |
0ms |
get settings: |
11ms |
get forum list: |
15ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
31ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
62ms |
get tp. blocked users: |
1ms |
others: | 265ms |
total: | 405ms |
0 / 0 |