потребовалось по быстрому проверить возвращает запрос что-то или нет.
думая, что select distinct /blabla limit 1 работает как select top 1 distinct /blabla в sql server запустил. жду, жду, жду, ... пока ждал, поматерился на тормоза, потом прошло времени столько, что успело дойти что этот болван делает.
ну как так-то? и нахрена так было сделано? может есть разумное объяснение такому поведению?
Здравствуйте, nikkit, Вы писали:
N>потребовалось по быстрому проверить возвращает запрос что-то или нет. N>думая, что select distinct /blabla limit 1 работает как select top 1 distinct /blabla в sql server запустил. жду, жду, жду, ... пока ждал, поматерился на тормоза, потом прошло времени столько, что успело дойти что этот болван делает. top 1 distinct — это сильно... наверное в постгресс просто не ожидали такого коварства....
Здравствуйте, nikkit, Вы писали:
N>ну как так-то? и нахрена так было сделано? может есть разумное объяснение такому поведению?
DISTINCT это автоматом GROUP BY, что тормознее даже, чем ORDER BY
По-хорошему надо SELECT EXISTS (SELECT 1 FROM ... WHERE ... LIMIT 1)
M>По-хорошему надо SELECT EXISTS (SELECT 1 FROM ... WHERE ... LIMIT 1)
я вообще всегда по возможности избегаю дистинкты. мопед не мой.
просто надо было быстро проанализировать запрос. в сиквеле после селекта тупо бы дописал топ 1 и был бы счастлив. тут во-первых писать в конце (еще раз через жопу) дак еще вот подстава )
N>я вообще всегда по возможности избегаю дистинкты. мопед не мой. N>просто надо было быстро проанализировать запрос. в сиквеле после селекта тупо бы дописал топ 1 и был бы счастлив. тут во-первых писать в конце (еще раз через жопу) дак еще вот подстава )
M>>По-хорошему надо SELECT EXISTS (SELECT 1 FROM ... WHERE ... LIMIT 1)
N>я вообще всегда по возможности избегаю дистинкты. мопед не мой. N>просто надо было быстро проанализировать запрос. в сиквеле после селекта тупо бы дописал топ 1 и был бы счастлив. тут во-первых писать в конце (еще раз через жопу) дак еще вот подстава )
То, что в MSSQL TOP 1 имеет более высокий приоритет над DISTINCT — вот это реальный трэш.
Нахрена тогда там вообще DISTINCT , так что и Postgres и Oracle в данном случае делают всё правильно и логично.
Если мне нужно первое из уникальных значений столбца — то надо сначала найти все уникальные. А не взять тупо первую строку и сделать по ней DISTINCT
--------------------------------------------------------------
Правильно заданный вопрос содержит в себе половину ответа
AN>То, что в MSSQL TOP 1 имеет более высокий приоритет над DISTINCT — вот это реальный трэш. AN>Нахрена тогда там вообще DISTINCT , так что и Postgres и Oracle в данном случае делают всё правильно и логично. AN>Если мне нужно первое из уникальных значений столбца — то надо сначала найти все уникальные. А не взять тупо первую строку и сделать по ней DISTINCT
нужно просто по-быстрому посмотреть возвращает ли чего запрос. все.
и где ты увидел логику — я хз. если вернется всего одна запись, как она может быть не дистинкт? дак нахрена же выполнять дистинкт сначала?
вот выберет он 10 записей, которые дистинкт. какую из них брать? или то что отсечет запрос не будет являться дистинкт, пока его не выполнить? ну бред же!
ну, конечно, может быть ситуация. когда на одной записи запрос падает, к примеру, да. но в этом случае я вообще не стану, к примеру, хотябы на первом шаге отладки его ограничивать. если цель типа понять что он вообще возвращает и вовзращает ли что-то.
Здравствуйте, nikkit, Вы писали:
N>потребовалось по быстрому проверить возвращает запрос что-то или нет. N>думая, что select distinct /blabla limit 1 работает как select top 1 distinct /blabla в sql server запустил. жду, жду, жду, ... пока ждал, поматерился на тормоза, потом прошло времени столько, что успело дойти что этот болван делает.
Здравствуйте, AndrewN, Вы писали: AN>То, что в MSSQL TOP 1 имеет более высокий приоритет над DISTINCT — вот это реальный трэш.
Хотелось бы увидеть пример таблицы, для которой такой приоритет операций приведёт к неверному результату.
"Реальный трэш" — это когда запрос выдаёт не то, что должен.
"Просто трэш" — это когда оптимизатор не использует какую-нибудь очевидную эквивалентность и перемалывает байты впустую.
А когда оптимизатор выбирает оптимальный способ исполнения запроса, гарантируя сохранение семантики — это как раз норма.
AN>Нахрена тогда там вообще DISTINCT , так что и Postgres и Oracle в данном случае делают всё правильно и логично. AN>Если мне нужно первое из уникальных значений столбца — то надо сначала найти все уникальные. А не взять тупо первую строку и сделать по ней DISTINCT
Вы бы ещё обиделись на то, что он при if exists(select * from tablename) не делает full table scan.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
На самом деле для человека, владеющего техниками оптимизации для SQL Server изучить оптимизацию для Postgres несложно, там примерно на порядок меньше вариантов операторов в плане, а множество типов индексов, которых нет в SQL Server, оптимизируют вполне конкретные функции.
Остается только разобраться с vacuum.
G>На самом деле для человека, владеющего техниками оптимизации для SQL Server изучить оптимизацию для Postgres несложно, там примерно на порядок меньше вариантов операторов в плане, а множество типов индексов, которых нет в SQL Server, оптимизируют вполне конкретные функции. G>Остается только разобраться с vacuum.
просто в отличие от sql server, на оракле и постгресс здравый смысл и интуицию использовать бесполезно. нужно обязательно читать мануалы
Здравствуйте, gandjustas, Вы писали: G>[sarcasm]Мне кажется MySQL и эффективность запросов — понятия несовместимые. [/sarcasm]
+1. Но вот тут дотошный студент попался, после моей лекции стал вопросами донимать, типа "почему вы считаете MySQL днищем". Я бегло порылся — везде какой-то детский лепет, начиная от элементарщины типа "используйте индексы, не тащите на клиента лишнего, в случае непоняток не стесняйтесь пользоваться EXPLAIN" и заканчивая бредом вроде "не надо выбирать лишние колонки во вложенных запросах, т.к. серверу придётся тяжело". Не могу поверить, что на плаву всё ещё остался движок, неспособный продвигать проекции вниз по дереву запросов.
Вот теперь ищу источник, на который можно авторитетно сослаться
G>По MySQL все описано тут https://dev.mysql.com/doc/refman/8.0/en/optimization.html
Спасибо большое. Посмотрим повнимательнее.
Вообще, похоже, за три мажорных релиза, прошедших с тех пор, как я на него смотрел в последний раз, ребята неплохо продвинулись
Вон, даже рекурсивные CTE прикрутили.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Видимо до 8 версии (2016 год) основная стратегия работы с подзапросами была — материализация. То есть любой подзапрос в запросе превращался в таблицу в памяти или на диске, к которой применялись операторы внешнего запроса.
Поэтому любой нетривиальный запрос превращался в страшно тормозное говно. Начиная с 8 версии начали появляться другие стратегии и оптимизации, например predicate pushdown https://dev.mysql.com/doc/refman/8.0/en/derived-condition-pushdown-optimization.html
S>Вообще, похоже, за три мажорных релиза, прошедших с тех пор, как я на него смотрел в последний раз, ребята неплохо продвинулись
Есть такое, но доверия пока мало. Опыт знакомых говорит что MySQL все еще нещадно тормозит на нетривиальных запросах.
S>Вон, даже рекурсивные CTE прикрутили.
По синтаксису и семантике запросов внезапно MySQL InnoDB очень близок к MsSQL, но работает заметно хуже.
G>>На самом деле для человека, владеющего техниками оптимизации для SQL Server изучить оптимизацию для Postgres несложно, там примерно на порядок меньше вариантов операторов в плане, а множество типов индексов, которых нет в SQL Server, оптимизируют вполне конкретные функции. G>>Остается только разобраться с vacuum.
N>просто в отличие от sql server, на оракле и постгресс здравый смысл и интуицию использовать бесполезно. нужно обязательно читать мануалы
здравый смысл ? и это про базу которая три десятилетия фигачила десяток типов блокировок которые так и ничего кроме дедлоков и не дали, все равно как у оракла и пострес версионность пришлось прикручивать ?
Здравствуйте, nikkit, Вы писали:
N>просто в отличие от sql server, на оракле и постгресс здравый смысл и интуицию использовать бесполезно. нужно обязательно читать мануалы
Мануалы нужно вообще читать, и лучше перед тем, как что-то собираешься сделать.
Здравствуйте, Sinclair, Вы писали:
S>+1. Но вот тут дотошный студент попался, после моей лекции стал вопросами донимать, типа "почему вы считаете MySQL днищем". Я бегло порылся — везде какой-то детский лепет, .....
Ты прочитал лекцию "MySQL — днище," а теперь ищешь аргументы, как это обосновать?
Многие и рады были бы испытать когнитивный диссонанс, но нечем.
Здравствуйте, gandjustas, Вы писали:
G>>>По MySQL все описано тут https://dev.mysql.com/doc/refman/8.0/en/optimization.html
… S>>Вообще, похоже, за три мажорных релиза, прошедших с тех пор, как я на него смотрел в последний раз, ребята неплохо продвинулись G>Есть такое, но доверия пока мало. Опыт знакомых говорит что MySQL все еще нещадно тормозит на нетривиальных запросах.
_FR>Оу, спасибо, смотрю они придумали воркэраунд (через CTE) для невозможности селф-джойна временной таблицы.
Ну так это же не временная таблица. Это не воркэраунд, это смена семантики запроса.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Gt_>здравый смысл ? и это про базу которая три десятилетия фигачила десяток типов блокировок которые так и ничего кроме дедлоков и не дали, все равно как у оракла и пострес версионность пришлось прикручивать ?
не там проблемы ищешь. с кривыми руками и соответственно архитектурой приложения можно положить что угодно.
Здравствуйте, nikkit, Вы писали:
n> Gt_>здравый смысл ? и это про базу которая три десятилетия фигачила десяток типов блокировок которые так и ничего кроме дедлоков и не дали, все равно как у оракла и пострес версионность пришлось прикручивать ? n> не там проблемы ищешь. с кривыми руками и соответственно архитектурой приложения можно положить что угодно.
Например, такое принципиально не лечится. Блокировочникам место в анналах истории.
Gt_>>здравый смысл ? и это про базу которая три десятилетия фигачила десяток типов блокировок которые так и ничего кроме дедлоков и не дали, все равно как у оракла и пострес версионность пришлось прикручивать ?
N>не там проблемы ищешь. с кривыми руками и соответственно архитектурой приложения можно положить что угодно.
можно положить что у годно, но это можно же было изначально положиться на здравый смысл и сделать нормально, у нас перед глазами оракл и постгрес. а у мсскл вышло порно которое пытались лечить всякими хинтами в стиле skip locked, блокировками намерений и прочей наркоманией. теперь в базе может быть пол транзакций блокировочные, другая на snapshot. и глядя на это ты нам втираешь про здравый смысл и интуицию ? да у мсскл основные счетчики спрятаны в performance мониторе винды, команды shirnk не отрабатывают по десятку причин, кластер, который и близко не кластер. не стоит втирать про здравый смысл с таким поделием.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, AndrewN, Вы писали: AN>>То, что в MSSQL TOP 1 имеет более высокий приоритет над DISTINCT — вот это реальный трэш. S>Хотелось бы увидеть пример таблицы, для которой такой приоритет операций приведёт к неверному результату.
стоит заменить (1) на что-то другое и поле примеров заметно расширится
S>"Реальный трэш" — это когда запрос выдаёт не то, что должен. S>"Просто трэш" — это когда оптимизатор не использует какую-нибудь очевидную эквивалентность и перемалывает байты впустую. S>А когда оптимизатор выбирает оптимальный способ исполнения запроса, гарантируя сохранение семантики — это как раз норма.
что, в оптимизаторе написан специальный кейс для top 1?
Здравствуйте, Константин Л., Вы писали:
КЛ>стоит заменить (1) на что-то другое и поле примеров заметно расширится
А, понятно. Ну, это просто непонимание семантики SQL. Приоритет операций надо задавать вложенными запросами.
select distinct * from (select top 10 ...);
S>>"Реальный трэш" — это когда запрос выдаёт не то, что должен. S>>"Просто трэш" — это когда оптимизатор не использует какую-нибудь очевидную эквивалентность и перемалывает байты впустую. S>>А когда оптимизатор выбирает оптимальный способ исполнения запроса, гарантируя сохранение семантики — это как раз норма.
КЛ>что, в оптимизаторе написан специальный кейс для top 1?
В хорошем — должен быть. Потому что разные алгоритмы джойна имеют разные оценки для времени получения первой записи и для времени получения последней записи.
Если у нас нет top, то надо выбирать алгоритм, который долго запрягает, но быстро ездит.
А если есть — то наоборот, надо выбирать алгоритм, который быстро выдаст начало. Даже если он в целом будет медленнее — неважно, ведь работа всё равно будет прервана после отдачи первых N записей.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Dym On, Вы писали:
N>>просто в отличие от sql server, на оракле и постгресс здравый смысл и интуицию использовать бесполезно. нужно обязательно читать мануалы DO>Мануалы нужно вообще читать, и лучше перед тем, как что-то собираешься сделать.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Константин Л., Вы писали:
КЛ>>стоит заменить (1) на что-то другое и поле примеров заметно расширится S>А, понятно. Ну, это просто непонимание семантики SQL. Приоритет операций надо задавать вложенными запросами. S>
S>select distinct * from (select top 10 ...);
S>
разность двух интуиций
КЛ>>что, в оптимизаторе написан специальный кейс для top 1? S>В хорошем — должен быть. Потому что разные алгоритмы джойна имеют разные оценки для времени получения первой записи и для времени получения последней записи. S>Если у нас нет top, то надо выбирать алгоритм, который долго запрягает, но быстро ездит. S>А если есть — то наоборот, надо выбирать алгоритм, который быстро выдаст начало. Даже если он в целом будет медленнее — неважно, ведь работа всё равно будет прервана после отдачи первых N записей.
Gt_>можно положить что у годно, но это можно же было изначально положиться на здравый смысл и сделать нормально, у нас перед глазами оракл и постгрес. а у мсскл вышло порно которое пытались лечить всякими хинтами в стиле skip locked, блокировками намерений и прочей наркоманией. теперь в базе может быть пол транзакций блокировочные, другая на snapshot. и глядя на это ты нам втираешь про здравый смысл и интуицию ? да у мсскл основные счетчики спрятаны в performance мониторе винды, команды shirnk не отрабатывают по десятку причин, кластер, который и близко не кластер. не стоит втирать про здравый смысл с таким поделием.
в запросах писать with(nolock) религия не позволяет?
Gt_>>можно положить что у годно, но это можно же было изначально положиться на здравый смысл и сделать нормально, у нас перед глазами оракл и постгрес. а у мсскл вышло порно которое пытались лечить всякими хинтами в стиле skip locked, блокировками намерений и прочей наркоманией. теперь в базе может быть пол транзакций блокировочные, другая на snapshot. и глядя на это ты нам втираешь про здравый смысл и интуицию ? да у мсскл основные счетчики спрятаны в performance мониторе винды, команды shirnk не отрабатывают по десятку причин, кластер, который и близко не кластер. не стоит втирать про здравый смысл с таким поделием.
N>в запросах писать with(nolock) религия не позволяет?
если цель показать на сколько далек мсскл от логики — да, можно и грязное чтение.
Здравствуйте, Константин Л., Вы писали:
КЛ>разность двух интуиций
КЛ>>>что, в оптимизаторе написан специальный кейс для top 1? S>>В хорошем — должен быть. Потому что разные алгоритмы джойна имеют разные оценки для времени получения первой записи и для времени получения последней записи. S>>Если у нас нет top, то надо выбирать алгоритм, который долго запрягает, но быстро ездит. S>>А если есть — то наоборот, надо выбирать алгоритм, который быстро выдаст начало. Даже если он в целом будет медленнее — неважно, ведь работа всё равно будет прервана после отдачи первых N записей.
КЛ>не для top n, для top 1
Ну вообще можно и для top 1, не убудет.
top 1 (ну в смысле limit 1) это довольно частый вариант, его оптимизация стоит того.
Оптимизатор в Постгресе говно, как ни крути.
Он потихоньку становится лучше. Но говна там все еще навалом.
Здравствуйте, Maniacal, Вы писали:
M>Здравствуйте, nikkit, Вы писали:
N>>ну как так-то? и нахрена так было сделано? может есть разумное объяснение такому поведению? M>DISTINCT это автоматом GROUP BY, что тормознее даже, чем ORDER BY
Нет не тормознее. Там банальный Hash Aggregate, т.е. запихивание значений в HashSet, что гораздо проще сортировки.
Здравствуйте, gandjustas, Вы писали:
G>На самом деле для человека, владеющего техниками оптимизации для SQL Server изучить оптимизацию для Postgres несложно, там примерно на порядок меньше вариантов операторов в плане, а множество типов индексов, которых нет в SQL Server, оптимизируют вполне конкретные функции. G>Остается только разобраться с vacuum.
На порядок, это сколько, в сравнении? Я просто немного с mssql знаком (с postgres знаком очень хорошо), а вы похоже наоборот.
Но я там не заметил на порядок большего количества типов шагов. в плане выполнения (про это я так понимаю речь?). А количество индексов в Постгресе не просто так, они для специфических типов данных (массивов, деревьев, geo координат и т.п.), которые отдельно в mssql не поддерживаются.
Здравствуйте, VladiCh, Вы писали:
VC>Здравствуйте, gandjustas, Вы писали:
G>>На самом деле для человека, владеющего техниками оптимизации для SQL Server изучить оптимизацию для Postgres несложно, там примерно на порядок меньше вариантов операторов в плане, а множество типов индексов, которых нет в SQL Server, оптимизируют вполне конкретные функции. G>>Остается только разобраться с vacuum.
VC>На порядок, это сколько, в сравнении?
Примерно в 10 раз, ну может быть в 5.
VC>Я просто немного с mssql знаком (с postgres знаком очень хорошо), а вы похоже наоборот.
Я хорошо знаком с обоими системами
VC>Но я там не заметил на порядок большего количества типов шагов.
Сравни https://learn.microsoft.com/en-us/sql/relational-databases/showplan-logical-and-physical-operators-reference https://www.postgresql.org/docs/15/runtime-config-query.html (к сожалению только перечень флагов, отключающих те или иные операторы)
VC>в плане выполнения (про это я так понимаю речь?). А количество индексов в Постгресе не просто так, они для специфических типов данных (массивов, деревьев, geo координат и т.п.), которые отдельно в mssql не поддерживаются.
Что вы такое говорите. Геотипы в MS SQL с соответствующими индексами поддерживаются с 2016 версии (7 лет)
Столько же работает JSON в колонках (массивы, деревья).
А еще есть inmemory, columnstore, графовые таблицы, не говоря уже о ledger databases и historical tables
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, VladiCh, Вы писали:
VC>>Здравствуйте, gandjustas, Вы писали:
G>>>На самом деле для человека, владеющего техниками оптимизации для SQL Server изучить оптимизацию для Postgres несложно, там примерно на порядок меньше вариантов операторов в плане, а множество типов индексов, которых нет в SQL Server, оптимизируют вполне конкретные функции. G>>>Остается только разобраться с vacuum.
VC>>На порядок, это сколько, в сравнении? G>Примерно в 10 раз, ну может быть в 5.
Бред же. Часть из них при этом просто операторы T-SQL типа If и While.
Часть относится специфически к кластерным индексам, которых нет в Постгресе (он любые типы индексов вообще рассматривает одинаково в плане),
часть к Parallel и Remote выполнению (опять же все есть в Постгресе но нет отдельный nodes для них).
Да и я вообще не поленился посчитать — в Postgres формально 42 типа, в MSSQL 110. Не дотягивает даже до 3x, не то что 5x или 10x. https://github.com/postgres/postgres/blob/aa210e0c121eb8f58c86d4fcc833a5a6fbb6f5a9/src/backend/executor/execProcnode.c#L166 — можно тут посмотреть
А учитывая то что я написал выше там реально и 2x не будет.
В pl/pgsql тоже есть while в общем то и много что еще, но ты не найдешь этого в планах.
Всякие Adaptive Join там тоже есть но не в качестве отдельных элементов плана.
Вы тут сравниваете яблоки с апельсинами, как говорится.
VC>>Я просто немного с mssql знаком (с postgres знаком очень хорошо), а вы похоже наоборот. G>Я хорошо знаком с обоими системами
Это вообще тут ни причем.
VC>>в плане выполнения (про это я так понимаю речь?). А количество индексов в Постгресе не просто так, они для специфических типов данных (массивов, деревьев, geo координат и т.п.), которые отдельно в mssql не поддерживаются. G>Что вы такое говорите. Геотипы в MS SQL с соответствующими индексами поддерживаются с 2016 версии (7 лет) G>Столько же работает JSON в колонках (массивы, деревья).
G>А еще есть inmemory, columnstore, графовые таблицы, не говоря уже о ledger databases и historical tables
Что толку то от этих графовых таблиц, я про типы индексов говорю. Есть columnstore, ok (из того чего нет в Postgres), хотя есть extension для этого (и еще для 100500 других вещей)
В обратную сторону там 4-5 типов индексов есть которых нет в MSSQL.