Подтвердить что ты не робот

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

Много кода SQL, который я прочитал, похоже, разработчик предполагает, что порядок сортировки по умолчанию всегда выполняется. Например, при создании списка выбора HTML они просто SELECT id, name FROM table не выдавали предложение ORDER BY.

Из моего собственного опыта кажется, что dbms всегда закачивает данные с использованием FIFO, если нет предложения ORDER BY и индекса нет. Однако заказ не гарантируется. Но я никогда не видел dbms переупорядочивания данных, если нет изменений в таблице.

Вы когда-нибудь испытывали выбор dbms в не детерминированном порядке, если нет изменений в таблице?

Лучше ли всегда ставить предложение ORDER BY?

4b9b3361

Ответ 1

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

Ответ 2

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

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

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

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

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

Ответ 3

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

Ответ 4

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

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

Ответ 5

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

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

Ответ 6

Если вы хотите, чтобы данные были заказаны, единственный способ гарантировать что-либо (с каждой основной системой RDBMS, о которой я знаю, определенно Sql Server и Oracle) должен включать предложение ORDER BY. FIFO не имеет абсолютно никакого отношения к тому, что данные заказа возвращаются без предложения ORDER BY, и нет никакого понятия о каком-либо порядке сортировки DEFAULT. Так называемый порядок сортировки по умолчанию DEFAULT, в основном, тем не менее, движок получает данные, которые могут быть буквально в любом порядке на основе индексов, кэшированных данных, одновременного выполнения запросов, загрузки на сервер и т.д. И т.д.

fooobar.com/questions/136207/... в основном охватывает ту же концепцию в отношении Sql Server, AlexK blogged repo, чтобы продемонстрировать поведение.

Ответ 7

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

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

Ответ 8

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

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

Поэтому лучше всего поставить ORDER BY, когда

  • Важным является порядок данных IS; и
  • Сортировка более эффективна на уровне БД.

то есть. если разработчик front-end будет "повторно сортировать" его в любом случае, тогда нет смысла, так как он вряд ли сохранит общее время обработки.

Ответ 9

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

Ответ 10

Я пишу это, если кто-то захочет использовать это, как и я.

Ну, я получаю удовлетворительный порядок сортировки по умолчанию, скажем, для журнальных таблиц, с сортировкой по индексу. Например, меня обычно интересуют последние строки таблицы журналов (LIFO), поэтому я делаю DateTime DESC в качестве порядка. Я также попытался добавить приложение Index в другое поле (целое число) рядом с основным ключом, и оно сработало.

CREATE TABLE [dbo].[tableA]([DateTime] [datetime] NOT NULL,
CONSTRAINT [PK_tableA] 
PRIMARY KEY CLUSTERED ([DateTime] DESC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]

Или в SSMS...

введите описание изображения здесь