Запрос Oracle, использующий 'как' на индексируемом столбце числа, низкой производительности

Я думаю, что другой аспект этого - то, что код - то, что важно. Это - то, что будет выполняемым. Например, в Вашем примере UML, я думал бы вместо того, чтобы иметь UML (по-видимому, созданный в некотором редакторе, не непосредственно связанный с "кодом") включенный в Ваш "исходный блоб" будет почти бесполезно. Намного лучше должен был бы генерировать UML непосредственно от Вашего кода, таким образом, это описывает точное состояние, код находится в как инструмент для понимания кода, а не как напоминание того, каков код должен был быть.

Мы делали это в течение многих лет относительно автоматизированных инструментов документа. В то время как сгенерированные комментарии фактического программиста в коде могли бы выйти из синхронизации с кодом, инструменты как JavaDoc и т.п. искренне представляют методы на объекте, возвращают типы, аргументы, и т.д. Они представляют их, поскольку они на самом деле существуют, не как некоторый артефакт, который вышел из бесконечных встреч дизайна.

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

Связанный с этим, объяснение того, почему Вы хотели бы использовать простой текст инструмент UML ( UMLGraph), кажется, применяется почти одинаково хорошо к тому, почему Вы хотите исходные файлы простого текста.

9
задан OMG Ponies 4 November 2009 в 19:39
поделиться

5 ответов

Условие сопоставления с образцом LIKE предполагает, что типы символов будут отображаться как левый и правый операнды. Когда он встречает ЧИСЛО, он неявно преобразует его в char. Ваш запрос 1 в основном незаметно переписывается следующим образом:

SELECT a1.*
  FROM people a1
 WHERE TO_CHAR(a1.id) LIKE '119%'
   AND ROWNUM < 5

Это происходит в вашем случае, и это плохо по двум причинам:

  1. Преобразование выполняется для каждой строки, что происходит медленно;
  2. Из-за функции ( хотя и неявно) в предикате WHERE, Oracle не может использовать индекс в столбце A1.ID .

Чтобы обойти это, вам необходимо выполнить одно из следующих действий:

  1. Создайте индекс на основе функций в столбце A1.ID :

    СОЗДАТЬ ИНДЕКС people_idx5 ON people (TO_CHAR (id));

  2. Если вам нужно сопоставить записи по первым 3 символам Столбец ID, создайте еще один столбец типа NUMBER, содержащий только эти 3 символа, и используйте для него простой оператор = .

  3. Создайте отдельный столбец ID_CHAR типа ] VARCHAR2 и заполните его TO_CHAR (id) . Проиндексируйте его и используйте вместо ID в вашем условии WHERE .

    Конечно, если вы решите создать дополнительный столбец на основе существующего столбца ID, вам необходимо синхронизировать эти 2 .Вы можете сделать это в пакетном режиме как одно ОБНОВЛЕНИЕ, или в триггере ON-UPDATE, или добавить этот столбец в соответствующие операторы INSERT и UPDATE в коде.

14
ответ дан 4 December 2019 в 13:02
поделиться

LIKE is a string function, so a numeric index can't be used as easily. In numeric index, you'll have 119,120,130,..,1191,1192,1193...,11921,11922... etc. That is all the rows starting with the '119' won't be in the same place, so the whole index has to be read (hence the FAST FULL SCAN). In a character based index they will be together (eg '119','1191','11911','120',...) so a better RANGE SCAN can be used.

If you were looking for id values in a particular range (eg 119000 to 119999) then specify that as the predicate (id between 119000 and 119999).

4
ответ дан 4 December 2019 в 13:02
поделиться

Оптимизатор решил, что сканирование таблицы выполняется быстрее, скорее всего, из-за малого количества фактических записей.

Кроме того, вы должны знать, что неточное соответствие всегда хуже точного . Если бы ваш where был «a1.id = '123456'», он, скорее всего, использовал бы index. Но опять же, даже для индекса требуется два чтения (сначала найти запись в индексе, затем прочитать блок из таблицы), а для очень маленьких таблиц он может решить сканирование таблицы.

1
ответ дан 4 December 2019 в 13:02
поделиться

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

0
ответ дан 4 December 2019 в 13:02
поделиться

Ключевое слово LIKE сообщает SQL, что вы выполняете сопоставление регулярного выражения. Вы никогда не должны использовать регулярные выражения в SQL или в любой библиотеке программирования, пока не проверите доступные строковые функции, чтобы увидеть, можно ли просто выразить запрос с их помощью. В этом случае вы можете изменить это на условие равенства, сравнив только подстроку, состоящую из первых 3 символов кода. В Oracle это будет выглядеть так:

SELECT *
FROM people
WHERE SUBSTR(code,1,3) = '119'
-3
ответ дан 4 December 2019 в 13:02
поделиться
Другие вопросы по тегам:

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