Лучшая практика SQL для контакта с порядком сортировки по умолчанию

Я придумал довольно наивный рекурсивный алгоритм (псевдокод):

Map<Object, List<Object>> source; // map of each object to its dependency list
List<Object> dest; // destination list

function resolve(a):
    if (dest.contains(a)) return;
    foreach (b in source[a]):
        resolve(b);
    dest.add(a);

foreach (a in source):
    resolve(a);

самая большая проблема с этим состоит в том, что это не имеет никакой способности обнаружить циклические зависимости - это может войти в бесконечную рекурсию (т.е. переполнение стека;-p). Единственный путь вокруг того, что я вижу, состоял бы в том, чтобы зеркально отразить рекурсивный алгоритм в интерактивный с ручным стеком, и вручную проверить стек на повторные элементы.

у Кого-либо есть что-то лучше?

33
задан Jim Ferrans 21 July 2014 в 02:09
поделиться

8 ответов

Там нет порядка сортировки по умолчанию. Даже если таблица имеет кластеризованный индекс, вам не гарантируется получение результатов в таком порядке. Вы должны использовать пункт order by, если вам нужен конкретный заказ.

49
ответ дан 27 November 2019 в 17:38
поделиться

Если вы хотите, чтобы данные выводились последовательно упорядоченными, да - вы должны использовать ORDER BY .

9
ответ дан 27 November 2019 в 17:38
поделиться

Да. Не существует «порядка по умолчанию» без ORDER BY, и нет гарантии, что вы получите данные обратно в FIFO / LIFO или любом другом порядке.

Что касается разработчиков, использующих «SELECT id, name FROM table» , они либо неумелые, либо им все равно, в каком порядке что-либо появляется.

6
ответ дан 27 November 2019 в 17:38
поделиться

Как упоминалось на других плакатах, если вы не укажете порядок сортировки, стандарт SQL говорит, что результаты могут быть в любом порядке, который обработчик запросов сочтет наиболее целесообразным и эффективным.

Допустим, вы выполняете простой неупорядоченный SELECT для всех строк таблицы CUSTOMER, не имеющей индексов и первичного ключа. Вполне возможно и даже вероятно, что обработчик запросов выполнит прямое сканирование таблицы и создаст строки в том порядке, в котором они были изначально вставлены (что даст вам поведение FIFO, которое вы видели).

Если вы затем добавите индекс в Поля STATE и CITY (в указанном порядке), а затем запрос WHERE STATE = 'NY' обработчик запросов может решить, что более эффективно сканировать записи индекса для STATE = 'NY', а не выполнять полное сканирование таблицы. В этом случае он, вероятно, материализует строки в порядке STATE, CITY.

Даже это не обязательно. Например, если обработчик запросов собрал статистику, которая показывает, что почти все значения STATE в вашей таблице - это «Нью-Йорк» (возможно, потому, что база данных предназначена для компании по аренде оборудования в Олбани), он может решить, что сканирование таблицы на самом деле дешевле. чем сканирование индекса, и вы снова увидите FIFO.

Хорошая идея - изучить некоторые основы того, как ваша база данных планирует свои запросы. Вы можете использовать оператор EXPLAIN , чтобы увидеть, как ваша СУБД будет выполнять любой заданный запрос, а затем использовать его для оптимизации вашего запроса, в некоторых случаях на порядок. Это увлекательная и полезная область для изучения.

Например, если обработчик запросов собрал статистику, которая показывает, что почти все значения STATE в вашей таблице - это «Нью-Йорк» (возможно, потому, что база данных предназначена для компании по аренде оборудования в Олбани), он может решить, что сканирование таблицы на самом деле дешевле. чем сканирование индекса, и вы снова увидите FIFO.

Хорошая идея - изучить некоторые основы того, как ваша база данных планирует свои запросы. Вы можете использовать оператор EXPLAIN , чтобы увидеть, как ваша СУБД будет выполнять любой заданный запрос, а затем использовать его для оптимизации вашего запроса, в некоторых случаях на порядок. Это увлекательная и полезная область для изучения.

Например, если обработчик запросов собрал статистику, которая показывает, что почти все значения STATE в вашей таблице - это «Нью-Йорк» (возможно, потому, что база данных предназначена для компании по аренде оборудования в Олбани), он может решить, что сканирование таблицы на самом деле дешевле. чем сканирование индекса, и вы снова увидите FIFO.

Хорошая идея - изучить некоторые основы того, как ваша база данных планирует свои запросы. Вы можете использовать оператор EXPLAIN , чтобы увидеть, как ваша СУБД будет выполнять любой заданный запрос, а затем использовать его для оптимизации вашего запроса, в некоторых случаях на порядок. Это увлекательная и полезная область для изучения.

он может решить, что сканирование таблицы на самом деле дешевле, чем сканирование индекса, и вы снова увидите FIFO.

Хорошая идея - изучить некоторые основы того, как ваша база данных планирует свои запросы. Вы можете использовать оператор EXPLAIN , чтобы увидеть, как ваша СУБД будет выполнять любой заданный запрос, а затем использовать его для оптимизации вашего запроса, в некоторых случаях на порядок. Это увлекательная и полезная область для изучения.

он может решить, что сканирование таблицы на самом деле дешевле, чем сканирование индекса, и вы снова увидите FIFO.

Хорошая идея - изучить некоторые основы того, как ваша база данных планирует свои запросы. Вы можете использовать оператор EXPLAIN , чтобы увидеть, как ваша СУБД будет выполнять любой заданный запрос, а затем использовать его для оптимизации вашего запроса, в некоторых случаях на порядок. Это увлекательная и полезная область для изучения.

17
ответ дан 27 November 2019 в 17:38
поделиться

Ни одна серьезная СУБД не гарантирует какой-либо порядок , если вы не укажете явный ORDER BY.

Все остальное - просто удача или случайность - если вы хотите порядок, вы должны укажите ORDER BY - никак иначе.

3
ответ дан 27 November 2019 в 17:38
поделиться

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

Типичный пример того, как Порядок изменения между выполнениями - это когда запрос выполняется с использованием параллельного плана. Поскольку параллельные операторы возвращают данные по мере того, как их производят базовые потоки, порядок строк в результате варьируется от каждого запуска. В этой ситуации даже простой SELECT в вашем примере при каждом запуске возвращает совершенно разные результаты.

3
ответ дан 27 November 2019 в 17:38
поделиться

Если вы хотите упорядочить данные, единственный способ гарантировать что-либо (со всеми известными мне крупными СУБД, определенно с Sql Server и Oracle) - это включить предложение ORDER BY. FIFO не имеет абсолютно ничего общего с данными о порядке, возвращаемыми без предложения ORDER BY, и нет концепции какого-либо порядка сортировки DEFAULT. Так называемый порядок сортировки ПО УМОЛЧАНИЮ в основном заключается в том, что движок получает данные, которые могут быть буквально в любом порядке на основе индексов, кэшированных данных, одновременного выполнения запросов, нагрузки на сервер и т. Д. И т. Д.

Этот другой поток stackoverflow в основном охватывает ту же концепцию в отношении Sql Server, AlexK опубликовал репозиторий , чтобы продемонстрировать поведение.

3
ответ дан 27 November 2019 в 17:38
поделиться

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

1
ответ дан 27 November 2019 в 17:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: