Ваши обходные пути стоят рядом с дополнительными узорами, -?
. Таким образом, всякий раз, когда обходные пути терпят неудачу, происходит откат назад, и встречаются нежелательные совпадения.
Чтобы избежать этого, учтите необязательный паттерн внутри паттернов внешнего вида.
/-?(?
См. regex demo
.
Сначала я переписал бы запрос, чтобы быть стандартом ANSI:
SELECT c.ClaimNumber, a.ItemDate, c.DTN, b.FilePath
FROM items a
INNER JOIN itempages b ON b.ItemNum = a.ItemNum
INNER JOIN keygroupdata c ON c.ItemNum = b.ItemNum
WHERE a.ItemType IN (112,115,189,241)
ORDER BY a.DateStored DESC
Это помогает считать и понять то, что продолжается. Это также помогает Вам не сделать ошибки (т.е. Перекрестное Присоединение), который мог бы вызвать реальные большие проблемы. Затем я получил бы Объяснить план видеть то, что DBMS делает с тем запросом. Это пытается использовать некоторые индексы? Это присоединяется к таблицам правильно?
Затем я рассмотрел бы таблицы, что я работаю с видеть, существуют ли какие-либо индексы, которые уже существуют, который я мог использовать для создания моего запроса быстрее. Наконец, поскольку все остальные предположили, что я удалил бы Порядок пунктом и просто сделал бы это в коде.
Удалите ORDER BY
выполните вид после задержки строк к приложению.
Если Вы говорите, что нет никаких индексов, то это также означает, что нет никаких первичных или определенных внешних ключей? Очевидно, анализ таблиц и сбор статистики важны, но если метаданные, такие как определение, как к таблицам, как предполагается, присоединяются, не существуют, затем Oracle может выбрать плохой путь выполнения.
В этом случае использование подсказки такой как /* + ПРИКАЗАЛО, чтобы */мог быть единственной опцией заставить оптимизатор надежно выбрать хороший путь выполнения. Это может также стоить добавить внешние ключи и первичные ключи, но определить их, как ОТКЛЮЧАЮТ и ПРОВЕРЯЮТ.
Я предполагаю, что полноценность этого комментария зависит от того, как далеко отвращение к индексам идет так YMMV.
В зависимости от типа данных столбца ItemType можно испытать более быстрое выполнение с помощью следующего, если это будет varchar, то Oracle сделает implict преобразования.
SELECT c.ClaimNumber, a.ItemDate, c.DTN, b.FilePath
FROM items a,
itempages b,
keygroupdata c
WHERE ((a.ItemType IN ('112','115','189','241'))
AND (a.ItemNum = b.ItemNum)
AND (b.ItemNum = c.ItemNum))
ORDER BY a.DateStored DESC
Иногда Вы видите преимущество путем добавления дополнительных трасс для оптимизатора для выбора путем добавления, что походит на избыточные элементы к где пункт.
Например, у Вас есть A.ItemNum = B.ItemNum И B.ItemNum = C.ItemNum. Попытайтесь добавить A.ItemNum = C.ItemNum также. Я вполне уверен, однако, что оптимизатор достаточно интеллектуален для понимания этого самостоятельно - стоящий попытки все же.
Статистические данные собраны на этих таблицах? В противном случае сбор статистики мог бы изменить план выполнения, хотя это не обязательно будет к лучшему.
Кроме этого, посмотрите на план выполнения. Можно видеть, что это присоединяется к таблицам в неоптимальном порядке (например, это могло присоединяться к b и c прежде, чем присоединиться к, который имеет условие фильтра).
Вы могли использовать подсказки, чтобы попытаться влиять на пути доступа, порядок соединения или метод соединения.
Обновление: Ответ на комментарий привел меня к этой презентации, которая могла бы быть полезной или по крайней мере интересной.
Действительно ли это - запрос, который Вы часто выполняете? Кажется, что это было бы в интересе владельца DB создать индексы, что необходимо ускорить этот запрос. Эти 3,5 минуты Вы тратите выполнение запроса, должны оказать некоторое влияние на свою продуктивную среду!
Кроме того, они выполняли статистику обновления по таблицам? Это могло бы улучшить производительность, поскольку порядок соединения вычисляется на основе статистики таблиц.
BTW, что Вам разрешают сделать? Просто читайте? Если можно составить временные таблицы и поместить индексы на тех, я мог бы рассмотреть делающие временные копии таблицы, индексировав их, и затем сделать помогшее с индексом соединение с временными копиями.
Без индексации тот запрос только собирается ухудшиться, когда размер таблицы увеличивается. После этих слов попытайтесь удалить порядок пунктом и сделать тот вид на стороне клиента.
Если исходные данные запроса являются постоянными или предсказуемыми ( itemType IN (...)
), затем альтернатива должна была бы выполнить запрос несколько раз день и сохранить результаты в локальной таблице с индексами в соответствующих случаях.
Можно затем сделать дорогостоящий запрос 'офлайн' и иметь более быстрые/лучше результаты для интерактивного запроса.
Можно попытаться фильтровать на типе изделия перед присоединением к таблицам, как показано здесь.
При работе Oracle до 9i это иногда приносило бы удивительную пользу.
select
c.claimnumber,
a.itemdate,
c.dtn,
b.filepath
from
(
select itemdate
from items it
where it.itemtype in(112,115,189,241)
) a
itempages b,
keygroupdata c
where a.itemnum = b.itemnum
and b.itemnum = c.itemnum
Можно также попытаться добавить подсказки / +RULE/или / +ORDERED/для наблюдения то, что происходит... снова, особенно с более старыми версиями, они иногда давали бы неожиданные результаты.
SELECT /*+RULE*/
c.ClaimNumber, a.ItemDate, c.DTN, b.FilePath
FROM
items a,
itempages b,
keygroupdata c
WHERE a.ItemType IN (112,115,189,241)
AND a.ItemNum = b.ItemNum
AND b.ItemNum = c.ItemNum
ORDER BY a.DateStored DESC
Во-первых, посмотрите на план выполнения. Это точно отражает количество строк, которые будут получены на каждом этапе выполнения запросов? Насколько выборочный предикат "a. ItemType В (112,115,189,241)"? План выполнения показывает какое-либо использование временного дискового пространства для соединений или видов?
На самом деле возможно, можно изменить вопрос включать план выполнения.
Также удостоверьтесь, что Вам не отключили хэширования, который иногда имеет место в настроенных на OLTP системах, поскольку они - самый эффективный способ данных объема equijoining в Oracle. Они должны обнаружиться в плане выполнения.
Попросите, чтобы третье лицо индексировало его объединяющие столбцы, поскольку они должны были сделать во-первых! Без индексов Oracle не имеет ничего для продолжения кроме грубой силы.
Можно хотеть попытаться создать осуществленное представление о любой из тех таблиц. Можно затем создать индекс на осуществленном представлении, которое поможет ускорить запрос (который затем запросил бы осуществленное представление вместо необработанной таблицы).
Конечно, если Ваша базовая таблица будет обновлена, то Ваше представление и индексы должны будут быть обновлены.