Oracle & Pagination - PullRequest
       30

Oracle & Pagination

6 голосов
/ 25 января 2010

У меня есть таблица оракула с количеством записей 99896618.

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

SELECT * FROM (select rownum rnum,f.* from  findings f where rownum<90000100 ) 
                    WHERE rnum > 90000000 

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

(Просто к сведению, я использую ASP.NET в качестве веб-технологии на стороне сервера и ADO.NET в качестве слоя доступа к данным и Silverlight для представления на стороне клиента)

Ответы [ 4 ]

6 голосов
/ 25 января 2010

Ваш запрос должен будет отсчитать первые 90M записи, чтобы получить следующие 100, поэтому вряд ли есть место для улучшения.

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

И вопрос: действительно ли ваши пользователи просматривают 900K страниц, прежде чем жаловаться на производительность?

Обновление:

Если вам нужна последняя страница, вам нужно переписать столбец ORDER BY в порядке убывания:

SELECT  *
FROM    (
        SELECT  rownum rnum, f.*
        FROM    findings f
        ORDER BY
                record_ordering_column DESC
        ) 
WHERE   rnum > 900
        AND rownum <= 100

и создайте индекс для record_ordering_column

Обратите внимание, что я смешиваю rownum из вложенных запросов для повышения производительности.

См. Эту статью в моем блоге для более подробной информации:

5 голосов
/ 25 января 2010

Из одного из ваших комментариев:

большую часть времени (около 95% времени) пользователи интересуются последними (последними) записями

В таком случае, почему бы не показать записи в обратном порядке, чтобы 95% времени пользователи интересовались страницей 1, а не страницей 900 000?

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

1 голос
/ 25 января 2010

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

0 голосов
/ 26 января 2010

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

Если вам все еще нужно получить весь ряд. Используйте следующий шаблон:

SELECT * FROM findings f1 WHERE f1.rowid IN
   (SELECT  rownum rnum, row_id
      FROM (
            SELECT f.rowid row_id
              FROM findings f
          ORDER BY record_ordering_column
           ) 
     WHERE rownum > 900
   )
WHERE rnum <= 100;

См. AskTom

Примечание: тонкое дополнительное предложение SELECT, а также использование запроса ROWID.

Если вы добавите индекс для record_ordering_column, тогда язычество будет использовать индекс для получения набора ROWID. Затем загружайте только блоки, содержащие строки, идентифицированные по их ROWID.

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

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