Как выбрать первые записи 'N' из базы данных, содержащей миллион записей?

Существуют ситуации, где это полезно, но в целом этого нужно избежать. Вы могли сравнить его с GOTO или поездкой на мопеде: Вы делаете это, когда Вы должны, но Вы не говорите Вашим друзьям об этом.

8
задан aJ. 10 September 2009 в 22:53
поделиться

4 ответа

Если ваша цель - найти 100 случайных строк и затем отсортировать их, тогда решение Лассе является правильным. Если, как я думаю, вы хотите, чтобы первые 100 строк были отсортированы по имени, а остальные отбросили, вы должны построить такой запрос:

SELECT * 
  FROM (SELECT * 
          FROM myTable 
         WHERE SIZE > 2000 ORDER BY NAME DESC) 
 WHERE ROWNUM <= 100

Оптимизатор поймет, что это запрос TOP-N, и сможет использовать индекс для NAME . Ему не нужно будет сортировать весь набор результатов, он просто начнет с конца индекса, прочитает его в обратном направлении и остановится после 100 строк.

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

SELECT /*+ FIRST_ROWS*/* FROM myTable WHERE SIZE > 2000 ORDER BY NAME DESC

Редактировать: просто добавление AND rownum <= 100 в запрос не будет работать, поскольку в Oracle rownum приписывается до сортировки: вот почему вы должны использовать подзапрос. Без подзапроса Oracle выберет 100 случайных строк и отсортирует их.

19
ответ дан 3 November 2019 в 14:03
поделиться

Добавьте это:

 AND rownum <= 100

в предложение WHERE.

Однако это не будет делать то, что вы просите.

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

Это может работать, но К сожалению, у меня нет сервера Oracle для тестирования:

SELECT *
FROM (
    SELECT *
    FROM myTable
    WHERE SIZE > 2000
      AND rownum <= 100
    ) x
ORDER BY NAME DESC

Но обратите внимание на «случайную» часть, вы говорите: «Дайте мне 100 строк с SIZE> 2000, мне все равно, какие 100».

Это действительно то, что вы хотите?

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

4
ответ дан 3 November 2019 в 14:03
поделиться

Этот показывает, как выбрать первые N строк в зависимости от вашей версии Oracle.

Начиная с Oracle 9i, RANK () и Функции DENSE_RANK () могут использоваться для определить TOP N строк. Примеры:

Получите 10 лучших сотрудников на основе их зарплата

ВЫБРАТЬ ename, sal FROM (SELECT ename, sal, RANK () OVER (ЗАКАЗАТЬ sal DESC) sal_rank FROM emp) WHERE sal_rank <= 10;

Выберите сотрудников, входящих в топ-10 зарплаты

ВЫБРАТЬ ename, sal FROM (SELECT ename, sal, DENSE_RANK () OVER (ЗАКАЗАТЬ ПО sal DESC) sal_dense_rank FROM emp) WHERE sal_dense_rank <= 10;

Разница между ними объясняется здесь

5
ответ дан 3 November 2019 в 14:03
поделиться

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

(Если столбец допускает значение NULL, это все еще возможно, либо ( a) добавление к запросу предиката NOT NULL или (b) добавление индекса на основе функций и соответствующее изменение предложения ORDER BY).

0
ответ дан 3 November 2019 в 14:03
поделиться
Другие вопросы по тегам:

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