2012-02-25 1 views
3

У меня есть ниже запрос, который возвращает 20000 записей из 100000000 после его выполнения ..вопрос производительности при заказе по п

SELECT * 
    FROM (SELECT a.*, ROWNUM rnum 
      FROM (select TIME,url,bytes 
        FROM (SELECT TO_CHAR ("5mintime",'YYYY-MM-DD HH24:MI:SS') AS TIME, url, BYTES 
          FROM available_web_details 
         WHERE "5mintime" >= TIMESTAMP '2012-02-10 00:00:00' 
          AND "5mintime" <= TIMESTAMP '2012-02-13 23:59:59' 
          AND username = 'asha1328874833' 
          AND CATEGORY = 'None240001'AND domain = '1328874833.vmware.com.' 
          AND (appid IN ('216.198.204.192id','216.198.207.0id','216.198.211.64id','216.198.211.128id','216.198.212.0id', '216.198.214.128id','216.198.214.192id','216.198.218.0id','216.198.220.192id','216.198.222.0id','216.198.223.32id','216.198.228.128id','216.198.229.128id',.....))) 
         ORDER BY TIME DESC) a 
       WHERE ROWNUM <= 10) 
     WHERE rnum > 0 

Она занимает около 5 минут, чтобы выполнить его. Но когда я удаляю предложение order by, он выполняется через 4 секунды. Можете ли вы предложить, как я могу улучшить производительность?

схема available_web_details:

Name   Null Type   
------------ ---- -------------- 
5mintime   TIMESTAMP(6) 
USERNAME   VARCHAR2(64) 
HOST    NUMBER   
SRC_ZONE   VARCHAR2(32) 
DOMAIN   VARCHAR2(512) 
DST_ZONE   VARCHAR2(32) 
CONTENT   VARCHAR2(64) 
CATEGORY   VARCHAR2(64) 
URL    VARCHAR2(1024) 
HITS    NUMBER   
BYTES    NUMBER   
APPID    VARCHAR2(32) 
APPLICATION  VARCHAR2(64) 
CATEGORYTYPE  VARCHAR2(64) 
USERGROUP   VARCHAR2(384) 

У меня есть индексы на AppID, "5mintime" с локальным разделом. available_web_details - это таблица разделов диапазона 1 месяц.

+0

Вы задумывались над индексацией? –

+0

@ roymustang86: Почему вы тратите свое время на свое бесполезное предложенное редактирование? –

+0

Вы можете вынуть предложение 'rnum> 0'? Я почти уверен, что ничего не сделаю. – eaolson

ответ

0

Вы пробовали изменить порядок от Time до 5mintime, я уверен, что вы не используете индекс при преобразовании значения и сортировке по нему.

+0

ye ..Я сделал это также в предыдущем запросе, заменив время на 5 минут, а индекс im с индексом на 5 минут, но все же он не дает производительности как тот же самый. Последний может быть способен завершить его через 30-45 секунд. предложите некоторые подсказки или так .. –

+0

Заказ будет штрафом за исполнение в любом случае - вы не можете ожидать такой же производительности, как и без заказа. – dbrin

+0

ye..thth's true..but, у меня есть JSP, чтобы показать этот результат в разбивке на страницы .. так что на каждой странице он попадает в тот же запрос, только bu меняет поле rownum от 10,20,30 ... так далее..so с очень низкой производительностью приложения. –

0

У вас есть указатель на 5 минут, поэтому закажите его, затем сделайте преобразование TO_CHAR во внешнем выборе. Вы можете также рассмотреть возможность индексирования других полей, которые вы используете в статьях WHERE.

Другая идея - посмотреть на план запросов, который использует Oracle, чтобы увидеть, как он приближается к проблеме. Вот хороший учебник по Oracle, explain plan: http://www.adp-gmbh.ch/ora/explainplan.html

+0

ye .. Я сделал это также в вышеуказанном запросе, заменив время на 5 минут, а индекс im с индексом на 5 минут, но все же он не дает производительности как тот же самый. По последним я должен быть способен завершить его за 30-45 секунд. вы можете предложить некоторые подсказки или около того. –

+0

Я отредактировал ссылку на учебное пособие по объяснению - это должно показать вам, как Oracle подходит к запросу, и позволяет определить, какие индексы используются и которые вам могут понадобиться создать, чтобы получить лучшую производительность. – craigmj

2

Давайте начнем с оговоркой: если не удалить, что order by или начать использовать временные таблицы, то время выполнения никогда собирается свести к 4s. Вторая оговорка: я допустил большую ошибку, которую исправляю сейчас; Мне пришлось слишком долго это осознавать. Спасибо Alex Poole.

Мои баллы (у меня всегда есть несколько).

  1. В комментариях были подняты некоторые очень действительные баллы, в частности, DimitryB. Если вы показываете только 10 записей за раз, тогда 20 000 строк равняются 2000 страницах. Ни один человек не собирается смотреть на всю эту информацию. Вы можете очень безопасно сократить количество записей, возвращаемых до 500, если не одна или две сотни.

  2. Непохожий пункт был поднят craigmj's answer, хотя я бы хотел его значительно расширить. По не индексировать все в where пункте и все в select вас гарантииtable access by index rowid. Это означает, что для каждой отдельной строки, которую вы возвращаете из вашего внутреннего select, вы вытащили из индекса, который также повторно подключился к таблице. Я признаю, что это был бы смехотворно большой индекс на вашем текущем столе.

  3. Вы, кажется, делаете еще один подвыбор, чем это необходимо. Вы можете разместить свой заказ в основном select. Вы также ссылаетесь на псевдоним a на двух уровнях выше псевдонима. Хотя это, вероятно, не вызовет каких-либо проблем, это немного запутанно, и вы в конечном итоге столбец rnum дважды.

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

  5. Следуя из пункта 5, вы разделили таблицу на месяц, но только выбираете данные за 3 дня. Я согласен с тем, что это разумно, но если вам нужно всего лишь на месячную сумму данных, чтобы быть легко доступным, возможно, стоило бы разбивать на день меньшую таблицу? Вы упомянули, что 2300 отчетов используют эту таблицу; если они все занимают 5 минут, тогда следует рассмотреть решительные методы, такие как это.

  6. Это немного трогательно, но есть ли необходимость в url быть 1024 символами?

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

Таким образом, шаги были бы:

  • Архив от все, что больше, чем один месяц в отдельную таблицу. Продолжайте делать это ежедневно.

  • Разделение меньшего стола на день.

  • Если вам нужны только несколько дней данных, то, безусловно, стоит подумать о создании materialized view, с заказом уже на месте.

  • Использовать «оптимальный» индекс на этот новый, меньший, стол; так что вам никогда не придется вообще прикасаться к столу. Я поставил перевернутые запятые вокруг оптимального, так как это всегда открыто для обсуждения, и мое предложение может быть немного неправильным, но обычно это все столбцы в where, group by, order by and select clauses в таком порядке и в порядке уменьшения избирательности. Это сделает ваш индекс примерно как "5mintime", username, category, domain, appid, url, bytes.

  • Сделайте индекс уникальным, если это вообще возможно.

  • Убедитесь, что ваш запрос не делает ничего, что ему не нужно, чтобы уменьшить рабочую нагрузку. Это включает в себя возвращение удобочитаемого числа строк. Я бы переписать его так:


SELECT time, url, bytes, rownum as rnum 
    FROM (SELECT time, url, bytes, rowum as rnum 
      FROM (SELECT TO_CHAR ("5mintime",'YYYY-MM-DD HH24:MI:SS') AS time 
         , url 
         , bytes 
        FROM available_web_details 
        WHERE "5mintime" BETWEEN to_timestamp('2012-02-10 00:00:00','YYYY-MM-DD HH24:MI:SS') 
          AND to_timestamp('2012-02-13 23:59:59','YYYY-MM-DD HH24:MI:SS') 
        AND username = 'asha1328874833' 
        AND category = 'None240001' 
        AND domain = '1328874833.vmware.com.' 
        AND appid IN ('216.198.204.192id',...) 
        ORDER BY "5mintime" DESC 
         ) 
     WHERE rownum <= 10) 
WHERE rnum > 0 

Надеюсь, все это имеет смысл; в конце дня объем работы, выполняемой на сервере по вашим отчетам, и скорость, с которой вы хотите их запустить, будут определять то, что вы хотите сделать.

+0

Являются ли ваши 'to_char' в условии where, который должен быть 'to_timestamp' с вашего четвертого пункта? И влияет ли 'to_char' в' order by' на использование необработанного столбца, положительного или отрицательного? –

+0

@AlexPoole, спасибо; Я не понял этого при повторном чтении. Для вашей второй точки да, вы правы, это было бы быстрее, но это также увеличило бы размер индекса, так как вам нужно было бы его индексировать, поэтому я не думаю, что это приведет к улучшению скорости. – Ben

+0

выше, это только один запрос отчета. У нас есть много таких запросов в одной таблице для разных отчетов, в которых изменяется условие предложения where.so, если я создаю индекс для каждого поля, которое используется там, где, упорядочивать, группировать и select clause.it может охватывать все комбинации полей таблицы .. !!!!! так что это возможно сделать .. ?? –

Смежные вопросы