2013-08-27 2 views
0

Показан индекс за столом invt_item_d на (item_id & branch_id & co_id) столбцов. Результаты плана для первого запроса: TABLE ACCESS FULL, а стоимость - 528, Результаты для второго запроса: INDEX FAST FULL SCAN (мой индекс) и стоимость: 27.разные столбцы на выбранных результатах запроса разные расходы

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

С этим что-то не так? И, пожалуйста, можете ли вы сказать мне, что мне делать, чтобы исправить это на уровне администрирования db?

select d.qty 
    from invt_item_d d 
where d.item_id = 999 
    and d.branch_id = 888 
    and d.co_id = 777 

select d.item_id 
    from invt_item_d d 
where d.item_id = 999 
    and d.branch_id = 888 
    and d.co_id = 777 

EDIT: я сделал новый запрос и стоимость, этот запрос является 529, с ТАБЛИЦЫ ACCESS FULL.

select qty from invt_item_d

так что не имеет значения, если я использовать индекс или нет. Некоторые говорят, что это нормально, действительно ли это нормальное поведение?

ответ

1

В первом случае к таблице должен быть доступ, так как столбец «qty» хранится только в таблице.

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

Вы можете добавить еще один индекс в столбцы (item_id, branch_id, co_id, qty), и он, скорее всего, будет использоваться в первом запросе.

Из документации Oracle: http://docs.oracle.com/cd/E11882_01/server.112/e25789/indexiot.htm

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

Быстрое полное сканирование индекса является альтернативой полного сканирования таблицы, когда оба из следующих условий:

  • Индекса должен содержать все столбцы, необходимые для выполнения запроса.

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

    • не нулевое ограничение

    • предикат применяется к нему, который предотвращает аннулирует из рассматриваемых в результате запроса набор

+1

@leitmotif первый ответ уже был правильный ответ (ИМХО), почему вы игнорируете это? –

+0

, потому что все столбцы в разделе where существуют в индексе. индекс не для того, что вы выбираете, для того, что вы фильтруете. поэтому, это не правильный ответ. – leitmotif

+0

@leitmotif - вы ошибаетесь. Столбцы в индексе могут использоваться также для того, что вы выбираете. Нет необходимости обращаться к таблице, если все данные уже присутствуют в индексе. –

0

Это точно главная цель использования индекса - сделать поиск FastE р. Запрос столбцов с индексами быстрее по сравнению с запросом столбцов без индексов.

Его основные знания оракула.

+0

Я думаю, что индексы имеют значение, когда вы используете столбцы с индексом в where where. – leitmotif

+0

в любом случае, я думаю, я неправильно понял, что ТАБЛИЦА ДОСТУПА ПОЛНО. было бы плохо, если бы это было полное сканирование таблицы. – leitmotif

+0

TABLE ACCESS FULL означало бы, что вся таблица (каждая строка) будет отсканирована, сравнена и соответствующие строки будут возвращены. Если таблица довольно огромная (несколько миллионов строк), персистент запроса будет страдать, то есть потребуется больше времени для выполнения. С меньшим количеством строк (скажем, несколько тысяч строк), однако, это не имеет большого значения. Я думаю, что вы правы, хотя эти индексы имеют значение, когда столбцы с индексом находятся в предложении where. Но по какой-то причине ваш первый запрос не попадает в индекс, но ваш второй запрос. – Arnab

0

Я добавляю еще один ответ, потому что это кажется более удобным.

Первый: «Я не попал в индекс, потому что есть 34000 строк, а не миллионы». Это ПОЛНОСТЬЮ НЕПРАВИЛЬНО и опасное понимание.

То, что я имел в виду, было, если несколько тысяч строк, и индекс не попал (движок oracle выполняет полное сканирование таблицы (ТАБЛИЦА ДОСТУПА ПОЛНОЕ)), это не очень важно. Oracle достаточно быстр, чтобы читать несколько тысяч строк за секунду (даже без индексов), и, следовательно, вы не почувствуете разницу. Запрос все еще медленнее (чем тот случай, когда есть индекс), но его минимально медленнее, чем вы не почувствуете разницы. Но если есть миллионы строк, выполнение запроса будет намного медленнее без индекса (так как на этот раз он сканирует миллионы строк в полном сканировании таблицы), и ваша производительность будет удалена.

Второе: почему вам нужно зацикливаться на столе с 34000 рядами, что слишком 4000 раз ??? Это ужасный подход. Избегайте петель в максимально возможной степени. Должен быть лучший подход!

В-третьих: Вы можете заставить оптимизатора оракула попасть в индекс с помощью подсказки индекса. Для этого вам нужно знать имя индекса.

select /*+ index(invt_item_d <index_name>) */ 
     d.qty 
    from invt_item_d d 
where d.item_id = 999 
    and d.branch_id = 888 
    and d.co_id = 777 

Вот link к переполнению стека вопроса на индекс намеком

+0

Я попытался заставить запрос использовать индекс, но он вернулся с худшими результатами. то я создал другую таблицу с той же структурой и индексами и вставил все 34000 строк в новую таблицу. то, когда я выполнил запрос с новой таблицей, результаты будут лучше (стоимость = 250). после этого я думал, что проблема связана с статистикой, выполняется статистика сбора для таблицы invt_item_d и для индекса, но все же я не получаю лучших результатов, даже если она немного ухудшилась (стоимость была 528, теперь она равна 550) – leitmotif