Oracle что быстрее distinct или group by

Обновлено: 04.07.2024

и я хочу получить все уникальные значения поля profession , что было бы быстрее (или рекомендовано):

Вы можете проверить себя так же быстро, как и задать вопрос. Вызывает раздражение то, что почти невозможно построить сценарий, в котором DISTINCT превосходит GROUP BY - что раздражает, потому что, очевидно, это не является целью GROUP BY. Однако GROUP BY может привести к вводящим в заблуждение результатам, что, я думаю, является достаточной причиной, чтобы этого избежать. Есть еще один дубликат с другим ответом. см. MySql - Отдельно от группы По <<< сказано, что GROUP BY лучше Пожалуйста, посмотрите здесь, если вы хотите измерить разницу во времени между запросами DISTINCT и GROUP BY.

Они по существу эквивалентны друг другу (на самом деле это то, как некоторые базы данных реализуют DISTINCT под капотом).

Если один из них быстрее, он будет DISTINCT . Это связано с тем, что, хотя оба они одинаковы, оптимизатор запросов должен уловить тот факт, что ваш GROUP BY не использует преимущества каких-либо членов группы, просто их ключи. DISTINCT делает это явным, поэтому вы можете уйти с немного более тупым оптимизатором.

Если вы сомневаетесь, проверьте!

DISTINCT будет быстрее, только если у вас нет индекса (так как он не сортируется). Когда у вас есть индекс, и он используется, это синонимы. Определение DISTINCT и GROUP BY отличаются тем, что DISTINCT не должен сортировать выходные данные, а GROUP BY по умолчанию делает. Однако в MySQL даже DISTINCT + ORDER BY может по- прежнему работать быстрее, чем GROUP BY из-за дополнительных подсказок для оптимизатора, как объясняется SquareCog. DISTINCT намного быстрее с большими объемами данных. Я проверил это и обнаружил, что в индексированном столбце mysql group by был примерно в 6 раз медленнее, чем отдельный с довольно сложным запросом. Просто добавив это как точку данных. Около 100 тысяч строк. Так что проверьте это и убедитесь сами.

Если у вас есть индекс на profession , эти два являются синонимами.

Если вы этого не сделаете, используйте DISTINCT .

GROUP BY в MySQL сортирует результаты. Вы даже можете сделать:

и ваши профессии отсортированы в порядке DESC .

DISTINCT создает временную таблицу и использует ее для хранения дубликатов. GROUP BY делает то же самое, но потом сортирует отдельные результаты.

быстрее, если у вас нет индекса на profession .

Вы можете добавить ORDER BY NULL в GROUP BY чтобы избежать сортировки.

Идём простейшим и самым коротким, если вы можете - DISTINCT, похоже, больше того, что вы ищете, только потому, что он даст вам ТОЧНО ответ, который вам нужен, и только это!

Все приведенные выше ответы верны, в случае DISTINCT в одном столбце против GROUP BY в одном столбце. Каждый движок db имеет свою собственную реализацию и оптимизацию, и если вы заботитесь о очень небольшой разнице (в большинстве случаев), вам нужно протестировать конкретную версию сервера и конкретной версии! Поскольку реализации могут меняться.

НО, если вы выберете более одного столбца в запросе, то DISTINCT существенно отличается! Потому что в этом случае он будет сравнивать ВСЕ столбцы всех строк, а не только один столбец.

Итак, если у вас есть что-то вроде:

Общей ошибкой считается мысль о том, что ключевое слово DISTINCT различает строки по указанному первому столбцу, но DISTINCT является ключевым словом в этом виде.

Итак, люди, которым вы должны быть осторожны, чтобы не принимать ответы выше, как правильные для всех случаев. Вы можете запутаться и получить неправильные результаты, пока все, что вы хотели, было оптимизировать!

Как-то на практике замечал, что GROUP BY работает быстрее, чем DISTINCT, но всё же такие запросы достаточно медленны. Можно ли как-то ускорить их? Я так понимаю, что индексы они не используют, или только у меня не используют
Подскажите плз выход.

Человек без чувства юмора - не серьёзный человек

DISTINCT, согласно описанию, выполняет неявный GROUP BY. Отличие в производительности может быть, но объяснить его рационально сложно. Индексы использует, но нужны правильные составные индексы, так как GROUP BY выполняется после WHERE. Поясню примером:

SELECT * from x WHERE y=10 GROUP BY z;

Требует индекс KEY(y,z)

Если индекса нет правильного, а есть только KEY(z), то использовать его не имеет смысла, так как придется накладывать на него условие y=10, а это в лучшем случае MERGE индексов, а в худшем, перебор таблицы.

А если в условии WHERE используется несколько полей, то индекса KEY(y,z) будет достаточно, если условие y=10 будет на первом месте? Или же нужен составной индекс на все поля?

Я так понимаю, что поле группировки в составном индексе должно быть последним?

Человек без чувства юмора - не серьёзный человек

Запрос:
SELECT * from x WHERE y1=10 AND y2=10 GROUP BY z;

Требует индекс KEY(y1,y2,z)

Кроме того, условие типа > или < обычно является последним, использующим индекс

Не совсем понял
Если у меня условие идёт по 10 полям, а группировка по одиннадцатому, которое не участвует в условии, для использования индекса при группировке нужен индекс на все 11 полей?

Человек без чувства юмора - не серьёзный человек

Именно так. MySQL сначала накладывает WHERE, затем группирует. Индекс может использоваться только один (за редким исключением ситуаций с MERGE индексов), соответственно последовательность в нем должна соответствовать последовательности использования - сначала 10 полей WHERE, затем 1 поле GROUP BY. Использование индекса остановится, если среди WHERE есть условия < или >

Вот использование < и > тоже интересно. Получается, при их использовании, значения не берутся из индекса и ускорить выборку уже никак нельзя?
В моих запросах есть и <, и >, и группировка. Значит, как я понимаю, включение поля группировки в использующийся индекс не имеет смысла?
Также, получается, что нет смысла включать в индекс поля, которые ищутся по условиям < и/или >? И тем более если таких полей несколько

Человек без чувства юмора - не серьёзный человек

Вот, к примеру, поле даты. Нужно найти записи, удовлетворяющие диапазону дат. Используем `date`>='date1' AND `date`<='date2'. Значит поле `date` не имеет смысла включать в индекс?

Человек без чувства юмора - не серьёзный человек

Neval написал:

Вот, к примеру, поле даты. Нужно найти записи, удовлетворяющие диапазону дат. Используем `date`>='date1' AND `date`<='date2'. Значит поле `date` не имеет смысла включать в индекс?

Это не так. Индекс используется для такого запроса. Но это последняя часть использованного составного индекса.

Пусть у Вас запрос WHERE a>10 and a<20 and b=11 and c=20
и индекс KEY(c,b, a) в таком случае последовательность такая:
1. Используется c=20 - первая часть индекса
2. Используется b=11 - вторая часть индекса
3. используется третья часть индекса для a>10 and a<20

Другой пример: KEY(c,a,b)
1. Используется c=20 - первая часть индекса
2. используется вторая часть индекса для a>10 and a<20
3. для оставшихся записей используется b=11 (using where), так как проще уже перебрать сами записи, чем обходить все ветви индекса для c=20, 10<a<20 и находить в индекса записи с b=11

Сразу не написал, но в моём случае в индексе есть два поля, каждое из которых ищется по больше/меньше, значит два этих поля точно нет смысла держать в индексе

А есть ли преимущество в использовании BETWEEN вместо больше/меньше?

Человек без чувства юмора - не серьёзный человек

BETWEEN синоним < >, преимущество не дает

Ваш случай просто проверьте, посмотрите что говорит EXPLAIN, какое значение key_len

и я хочу получить все уникальные значения profession поле, что было бы быстрее (или рекомендуется):

они по существу эквивалентны друг другу (на самом деле это как некоторые базы данных реализации DISTINCT под капотом).

если один из них быстрее, это будет DISTINCT . Это связано с тем, что, хотя оба они одинаковы, оптимизатор запросов должен был бы поймать тот факт, что ваш GROUP BY не использует никаких членов группы, только их ключи. DISTINCT делает это явным, поэтому вы можете уйти с немного более тупым оптимизатором.

когда в сомнении, тест!

если у вас есть индекс на profession эти два слова-синонимы.

если нет, то используйте DISTINCT .

GROUP BY на MySQL результаты разные. Вы даже можете сделать:

и получить ваши профессии отсортированы в DESC порядок.

DISTINCT создает временную таблицу и использует его для хранения дубликатов. GROUP BY делает то же самое, но сортирует различные результаты впоследствии.

быстрее, если у вас нет индекса на profession .

перейти на самый простой и короткий, если вы можете -- DISTINCT, кажется, больше того, что вы ищете только потому, что он даст вам именно тот ответ, который вам нужен, и только это!

все ответы выше верны, для случая DISTINCT на одном столбце vs GROUP BY на одном столбце. Каждый движок БД имеет свою собственную реализацию и оптимизацию, и если вы заботитесь о очень маленькой разнице (в большинстве случаев), то вам нужно протестировать против конкретного сервера и конкретной версии! Как реализации могут измениться.

но, если вы выбираете более одного столбца в запросе, то DISTINCT существенно отличается! Потому что в этом случае это будет сравнить все столбцы всех строк, а не только один столбец.

Так что если у вас есть что-то вроде:

Это распространенная ошибка думать, что ключевое слово DISTINCT различает строки по первому столбцу, который вы указали, но DISTINCT является общим ключевым словом таким образом.

таким образом, люди, Вы должны быть осторожны, чтобы не принимать ответы выше как правильные для всех случаев. Вы можете запутаться и получить неправильные результаты, в то время как все, что вы хотели, было оптимизация!

well distinct может быть медленнее, чем group by в некоторых случаях в postgres (не знаю о других dbs).

Так что будьте осторожны . :)

группы по дороже, чем отличие с группой не на результат, а особым избегает его. Но если вы хотите сделать group BY дать тот же результат, что и distinct give порядок по null ..

равна

похоже, что запросы не совсем одинаковы. По крайней мере для MySQL.

  1. опишите выберите отдельное имя продукта из northwind.продукты
  2. опишите выберите productname из northwind.Products group by productname

второй запрос дает дополнительно "использование filesort" в Extra.

на в MySQL," Group By " использует дополнительный шаг: filesort . Я понимаю DISTINCT быстрее GROUP BY и это был сюрприз.

(более функциональное Примечание)

есть случаи, когда вам нужно использовать GROUP BY, например, если вы хотите получить количество сотрудников на работодателя:

в таком случае DISTINCT u.employer работает неправильно. Возможно, есть способ, но я просто не знаю его. (Если кто-то знает, как сделать такой запрос с DISTINCT, пожалуйста, добавьте Примечание!)

Если вам не нужно выполнять какие-либо групповые функции (sum, average и т. д., Если вы хотите добавить числовые данные в таблицу), используйте SELECT DISTINCT. Я подозреваю, что это быстрее, но у меня нет ничего, чтобы показать это.

в любом случае, если вы беспокоитесь о скорости, создать индекс по столбцу.

после тяжелых испытаний мы пришли к выводу, что GROUP BY быстрее

выберите sql_no_cache opnamegroep_intern От telwerken Где opnemergroep IN (7,8,9,10,11,12,13) группа по opnamegroep_intern

635 totaal 0.0944 сек Weergave van records 0-29 (635 totaal, query duurde 0.0484 sec)

выберите sql_no_cache distinct (opnamegroep_intern) От telwerken Где opnemergroep IN (7,8,9,10,11,12,13)

635 totaal 0.2117 секунд ( почти 100% медленнее ) Weergave van records 0-29 (635 totaal, query duurde 0.3468 sec)

для каждого запроса . попробуйте отдельно, а затем группируйте . сравните время, чтобы завершить каждый запрос и использовать быстрее .

в моем проекте когда-то я использую group by и другие distinct

вот простой подход, который будет печатать 2 разных времени для каждого запроса.

Он просто отображает количество миллисекунд, необходимых для анализа, компиляции и выполнения каждого оператора, как показано ниже:

SELECT DISTINCT всегда будет одинаковым или быстрее, чем GROUP BY. В некоторых системах (например, Oracle) он может быть оптимизирован так же, как и для большинства запросов. На других (например, SQL Server) это может быть значительно быстрее.

Если проблема позволяет это, попробуйте с EXISTS, так как она оптимизирована для завершения, как только результат будет найден (и не буферизуйте какой-либо ответ), поэтому, если вы просто пытаетесь нормализовать данные для предложения WHERE, как это

Я пытаюсь улучшить время запросов для существующего приложения с базами данных Oracle, которое работает немного вяло. Приложение выполняет несколько больших запросов, например, приведенное ниже, которое может занять более часа. Замена DISTINCT на предложение GROUP BY в запросе ниже сокращает время выполнения от 100 минут до 10 секунд. Я понял, что SELECT DISTINCT и GROUP BY работают примерно так же. Почему такое огромное несоответствие между сроками исполнения? В чем разница в том, как выполняется запрос в фоновом режиме? Есть ли ситуация, когда SELECT DISTINCT работает быстрее?

Примечание. В следующем запросе WHERE TASK_INVENTORY_STEP.STEP_TYPE = 'TYPE A' представляет собой лишь один из нескольких способов, по которым результаты могут быть отфильтрованы. Этот пример был предоставлен, чтобы показать аргументы в пользу объединения всех таблиц, в которых нет столбцов, включенных в SELECT , и приведет к десятой части всех доступных данных.

SQL с помощью DISTINCT :

SQL с помощью GROUP BY :

Вот план запросов Oracle для запроса с помощью DISTINCT :

Oracle query plan for query using DISTINCT

Вот план запросов Oracle для запроса с помощью GROUP BY :

Oracle query plan for query using GROUP BY

Разница в производительности, вероятно, связана с выполнением подзапроса в предложении SELECT . Я предполагаю, что он повторно выполняет этот запрос для каждой строки перед отдельными. Для group by он будет выполняться один раз после группы.

Попробуйте заменить его на соединение, вместо этого:

Я уверен, что GROUP BY и DISTINCT имеют примерно один и тот же план выполнения.

Разница здесь, поскольку мы должны угадать (поскольку у нас нет планов объяснений) является IMO, что встроенный подзапрос выполняется ПОСЛЕ GROUP BY , но ПЕРЕД DISTINCT .

Итак, если ваш запрос возвращает 1M строк и объединяется в 1k строк:

  • Запрос GROUP BY выполнил бы подзапрос 1000 раз,
  • В то время как запрос DISTINCT выполнил бы подзапрос 1000000 раз.

План объяснения tkprof поможет продемонстрировать эту гипотезу.

Пока мы обсуждаем это, я думаю, важно отметить, что способ написания запроса вводит в заблуждение как для читателя, так и для оптимизатора: вы, очевидно, хотите найти все строки из item/item_transactions, у которых есть TASK_INVENTORY_STEP.STEP_TYPE со значением "ТИП А".

ИМО у вашего запроса был бы лучший план, и было бы легче читать, если бы оно написано следующим образом:

Во многих случаях DISTINCT может быть признаком того, что запрос написан неправильно (поскольку хороший запрос не должен возвращать дубликаты).

Обратите внимание также, что в исходном select не используются 4 таблицы.

Прежде всего следует отметить, что использование Distinct указывает на запах кода, например, на анти-шаблон. Обычно это означает, что отсутствует соединение или дополнительное соединение, которое генерирует повторяющиеся данные. Рассматривая ваш запрос выше, я предполагаю, что причина, по которой group by работает быстрее (без просмотра запроса), заключается в том, что расположение group by уменьшает количество записей, которые в итоге возвращаются. В то время как Distinct выдувает результирующий набор и выполняет сравнение строк за строкой.

Обновить для приближения

Извините, я должен был быть более ясным. Записи генерируются, когда пользователи выполняют определенные задачи в системе, поэтому нет расписания. пользователь может генерировать одну запись за день или сотни в час. важно то, что каждый раз, когда пользователь запускает поиск, обновляется записи должны быть возвращены, что заставляет меня сомневаться в том, что материализованная просмотр будет работать здесь, особенно если запрос, заполняющий его, будет долго работать.

Я верю, что это точная причина использовать материализованное представление. Таким образом, процесс будет работать таким образом. Вы берете длинный запрос как часть, которая создает материализованное представление, поскольку мы знаем, что пользователь заботится только о "новых" данных после выполнения какой-либо произвольной задачи в системе. Итак, что вы хотите сделать, это запрос к этому материализованному представлению базы данных, которое может постоянно обновляться в фоновом режиме, стратегия стратегии сохранения не должна заглушать материализованное представление (сохраняя несколько сотен записей за раз, не будет раздавить что-либо). То, что это позволит, - это Oracle, чтобы захватить блокировку чтения (обратите внимание, что нам все равно, сколько источников читает наши данные, мы только заботимся о писателях). В худшем случае пользователь будет иметь "устаревшие" данные за микросекунды, поэтому, если это не будет финансовая торговая система на Уолл-стрит или система для ядерного реактора, эти "блики" должны остаться незамеченными даже у самых орел-пользователей.

Пример кода, как это сделать:

Теперь ключ к этому - до тех пор, пока вы не вызываете обновление, вы не потеряете ни одной из сохраненных данных. Вам будет нужно определить, когда вы хотите "базовую линию" получить свое материализованное представление (возможно, полночь?)

и я хочу получить все уникальные значения profession поля, что будет быстрее (или рекомендуется):

Вы можете проверить себя так же быстро, как и задать вопрос. Раздражает то, что почти невозможно построить сценарий, в котором DISTINCT превосходит GROUP BY - что раздражает, потому что, очевидно, это не является целью GROUP BY. Однако GROUP BY может привести к вводящим в заблуждение результатам, что, я думаю, является достаточной причиной, чтобы этого избежать. Есть еще один дубликат с другим ответом. см. MySql - Отдельно от группы К <<< говорится, что GROUP BY лучше Пожалуйста, посмотрите здесь, если вы хотите измерить разницу во времени между запросами DISTINCT и GROUP BY.

Они по существу эквивалентны друг другу (фактически, это то, как некоторые базы данных реализуются DISTINCT под капотом).

Если один из них быстрее, он будет DISTINCT . Это связано с тем, что, хотя они одинаковы, оптимизатору запросов придется уловить тот факт, что вы GROUP BY не пользуетесь никакими членами группы, а только их ключами. DISTINCT делает это явным, так что вы можете обойтись немного более тупым оптимизатором.

Если есть сомнения, проверьте!

DISTINCT будет быстрее, только если у вас нет индекса (так как он не сортируется). Когда у вас есть индекс, и он используется, это синонимы. Определение DISTINCT и GROUP BY отличается тем, что DISTINCT не нужно сортировать вывод, и GROUP BY по умолчанию делает. Однако, в MySQL даже DISTINCT + ORDER BY может еще быстрее , чем GROUP BY из - за дополнительные подсказки для оптимизатора , как объяснена SquareCog. DISTINCT намного быстрее с большими объемами данных. Я проверил это и обнаружил, что в индексируемом столбце mysql group by был примерно в 6 раз медленнее, чем отдельный с довольно сложным запросом. Просто добавив это как точку данных. Около 100 тысяч строк. Так что проверьте это и убедитесь сами.

Если у вас есть индекс profession , эти два являются синонимами.

Если нет, то используйте DISTINCT .

GROUP BY в MySQL сортировке результатов. Вы даже можете сделать:

и приведите свои профессии в DESC порядок.

DISTINCT создает временную таблицу и использует ее для хранения дубликатов. GROUP BY делает то же самое, но сортирует отличные результаты впоследствии.

быстрее, если у вас нет индекса на profession .

Вы можете добавить ORDER BY NULL к, GROUP BY чтобы избежать сортировки. @Quassnoi groupby медленнее, чем отчетливый, даже если избегать сортировки Примечание. В MySQL 8 классификаторы заказов на GROUP BY устарели.

Все ответы выше верны, для случая DISTINCT в одном столбце против GROUP BY в одном столбце. Каждый механизм БД имеет свою собственную реализацию и оптимизацию, и если вы заботитесь об очень небольшой разнице (в большинстве случаев), то вам придется тестировать на конкретном сервере И на конкретной версии! Как реализации могут измениться .

НО, если вы выберете более одного столбца в запросе, то DISTINCT существенно отличается! Потому что в этом случае он будет сравнивать ВСЕ столбцы всех строк, а не только один столбец.

Так что если у вас есть что-то вроде:

Распространенной ошибкой считается, что ключевое слово DISTINCT различает строки по первому указанному вами столбцу, но DISTINCT является общим ключевым словом в этом смысле.

Таким образом, люди, с которыми вы должны быть осторожны, чтобы не принимать приведенные выше ответы как правильные для всех случаев . Вы можете запутаться и получить неправильные результаты, в то время как все, что вам нужно, это оптимизировать!

Читайте также: