Есть ли SQL ANSI способ начать поиск в конце таблицы? - PullRequest
4 голосов
/ 10 августа 2010

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

Ответы [ 10 ]

4 голосов
/ 10 августа 2010

В спецификации SQL ничего не говорится о поддержании порядка вставки. На практике большинство приличных БД также не поддерживают его. Тогда это останавливается здесь. Сортировка таблицы сначала не сделает это быстрее. Просто внесите в указатель интересующий вас столбец (столбцы), которые вы используете в WHERE.

3 голосов
/ 10 августа 2010

Один из «принципов» правильной СУБД заключается в том, что такого рода вопросы не должны касаться вас или любого другого лица, использующего БД.

Механизм БД «свободен» для использования любого метода, который он хочет хранить / извлекать записи, поэтому, если вы хотите применить «верхнее» поведение, сделайте то, что предложили другие: добавьте поле временной метки в таблицутаблицы), добавьте к нему индекс и выполните запрос, используя его в качестве критерия сортировки и / или запроса (например, вы опрашиваете таблицу каждую минуту и ​​запрашиваете записи с отметкой времени> = systime-1 минута)

3 голосов
/ 10 августа 2010

Стандартного способа не существует.

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

SQL Server позволяет записывать ASC или DESC в индекс:

[ASC | DESC]

Определяет восходящее или нисходящее направление сортировки для конкретного столбца индекса. По умолчанию используется ASC.

В MySQL вы также можете написать ASC или DESC при создании индекса, но в настоящее время это игнорируется. Это может быть реализовано в будущей версии.

2 голосов
/ 10 августа 2010

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

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

2 голосов
/ 10 августа 2010
  1. Если ваши данные проиндексированы, это не имеет значения. Индекс выполняет бинарный поиск, а не последовательное сканирование.
  2. Если вы не делаете TOP 1 (или что-то подобное), SELECT все равно придется сканировать всю таблицу или индекс.
2 голосов
/ 10 августа 2010

Добавьте счетчик или поле времени в таблицу, отсортируйте ее и получите верхние строки.

Другими словами: вам следует забыть, что по умолчанию к таблицам SQL обращаются в любом конкретном порядке. Последовательность не означает, что сначала будут искать самые старые строки, только то, что будут проверены все строки. Если вы хотите оптимизировать поиск, добавьте индексы в некоторые поля. То, что вы ищете, это, вероятно, индексы.

1 голос
/ 10 августа 2010

Вы не можете сделать это.

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

Некоторые РСУБД позволяют вам объявлять обратный индекс, то есть тот, который идет по убыванию, а не по возрастанию.Если вы создаете обратный индекс в поле идентификатора, и если оптимизатор использует этот индекс, он сначала просмотрит самые последние записи.Это даст вам быстрый ответ для первого ряда.

Следующий шаг - заставить оптимизатор использовать индекс.Вам нужно использовать план объяснения, чтобы увидеть, используется ли индекс.Если вы запрашиваете строки в порядке убывания идентификатора, оптимизатор почти наверняка будет использовать обратный индекс.Если нет, то вы можете использовать подсказки для руководства оптимизатором.

Если вам все еще нужно избегать чтения всех строк, чтобы не тратить время, вы можете использовать функцию LIMIT, чтобы объявить, что выхочу только, скажем, 10 строк и не более, или 1 ряд и не более.Это должно сделать это.

Удачи.

1 голос
/ 10 августа 2010

Стандарт SQL ISO / ANSI вообще не учитывает оптимизацию.Например, широко распространенный CREATE INDEX SQL DDL не указан в Стандарте.Это связано с тем, что Стандарт не делает никаких предположений о базовом носителе данных и не должен этого делать.Я регулярно использую SQL для запроса данных в текстовых файлах и электронных таблицах Excel, ни у одной из которых нет понятия индексов базы данных.

1 голос
/ 10 августа 2010

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

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

Создайте «промежуточную» таблицу, которая точно имитирует структуру вашей таблицы.Всякий раз, когда вы вставляете в свой основной стол, также вставляйте в свою «промежуточную» область.Ограничьте вашу «промежуточную» область n строками, используя триггер для удаления строки идентификатора низший в таблице, когда будет достигнута новая строка сверх вашего произвольного максимума (скажем, 10000 или что-то еще)ваш лимит).

Затем запросы могут сначала попасть в эту меньшую таблицу в поисках информации.Поскольку таблица произвольно ограничена последними n строками, она просматривает только самые последние данные.Только если не удастся найти совпадение, ваш запрос (на самом деле, на данный момент хранимая процедура из-за принятия решения) попадет в вашу главную таблицу.

Некоторые ошибки:1) Убедитесь, что ваш триггер (-ы) настроен (-ы) правильно, чтобы поддерживать правильный параллелизм между вашими «основными» и «промежуточными» таблицами.2) Это может быстро стать кошмаром технического обслуживания, если не будет должным образом обработано, и в зависимости от вашего сценария это будет немного сложнее.3) Я не могу не подчеркнуть, что это эффективно / полезно только в очень специфических сценариях.Если ваш не соответствует, используйте один из ответов.

0 голосов
/ 10 августа 2010

Если ваша таблица имеет дату создания, я бы отсортировал ее по обратному порядку и взял бы верхнюю 1.

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