Что означает +0 после ORDER BY в Oracle - PullRequest
9 голосов
/ 07 июля 2010

Я пытаюсь понять, что означает +0 в конце этого запроса Oracle 9i:

SELECT /*+ INDEX (a CODE_ZIP_CODE_IX) */ 
       a.city, 
       a.state, 
       LPAD(a.code,5,0)  ZipCode, 
       b.County_Name     CoName, 
       c.Description     RegDesc, 
       d.Description     RegTypeDesc  
FROM TBL_CODE_ZIP a, 
     TBL_CODE_COUNTY b, 
     TBL_CODE_REGION c, 
     TBL_CODE_REGION_TYPE d  
WHERE a.City = 'LONDONDERRY' 
    AND a.State = 'NH' 
    AND lpad(a.Code,5,0) = '03038' 
    AND a.Region_Type_Code = 1 
    AND b.County(+) = a.County_Code  
    AND b.STATE(+) = a.STATE 
    AND c.Code(+) = a.Region_Code  
    AND d.Code(+) = a.Region_Type_Code  
ORDER BY a.Code +0

Есть идеи?

ПРИМЕЧАНИЕ: я не думаю, что это должноделать с восходящим или нисходящим, так как я не могу добавить asc или desc между a.Code и +0, и я могу добавить asc или desc после + 0

Ответы [ 5 ]

8 голосов
/ 08 июля 2010

+ 0 был хитростью еще во времена оптимизатора на основе правил, что делало невозможным использование индекса для числового столбца. Точно так же они сделали || '' для буквенно-цифровых столбцов.

По вашему запросу, единственный вывод, который я могу сделать после проверки, состоит в том, что его создатель боролся с производительностью. Если (это мое предположение) индекс CODE_ZIP_CODE_IX является индексом TBL_CODE_ZIP (Код), то запрос не будет использовать его, даже если намекнут на его использование. Создатель, вероятно, не знал, что при использовании LPAD (a.code, 5,0) вместо a.code индекс не может быть использован. Предложение order by берет свой промежуточный набор результатов - который находится в памяти - и сортирует его. Для этого не нужен индекс. Но с + 0 похоже, что он думал отключить его.

Итак, уловки, которые использовались, были неэффективны, и теперь, как вы выяснили, только вводят в заблуждение.

С уважением, Роб.

PS1: лучше использовать LPAD (TO_CHAR (a.code), 5, '0') или TO_CHAR (a.code, 'fm00009'). Тогда понятно, что вы делаете с типом данных.

PS2. Вашему запросу может быть полезно использовать индекс на основе функций для LPAD (TO_CHAR (a.code), 5, '0') или любое другое выражение, которое вы используете для заполнения своего почтового индекса слева.

7 голосов
/ 07 июля 2010

Я полагаю, что a.code - это VARCHAR2, содержащий числовую строку, и +0 фактически преобразует его в NUMBER, поэтому сортировка будет числовой, а не альфа

. Вы должны иметь возможностьдобавить ASC / DESC после + 0

3 голосов
/ 07 июля 2010

Примечание: я удалил этот ответ, потому что Марк Б был быстрее машинистки. Тем не менее, я восстановил его, потому что я думаю, что есть некоторая ценность в демонстрации того, что, возможно, было основным намерением SQL, который опубликовал Лукас.


Предположим, CODE - это столбец VARCHAR2, содержащий строки цифр (почтовые индексы). Проблема в том, что varchars сортируются как строки, а не числа. Добавление нуля к КОДУ порождает неявное приведение к числу, и, следовательно, сортирует по численности:

SQL> select id, code
  2  from t72
  3  order by code
  4  /

        ID CODE
---------- -----
         1 1
         2 11
         3 111
         4 12

SQL> select id, code
  2  from t72
  3  order by code+0
  4  /

        ID CODE
---------- -----
         1 1
         2 11
         4 12
         3 111

SQL>

Если бы сохраненные коды были дополнены нулями слева, приведение не было бы необходимости, так как в любом случае они сортировались бы в числовом порядке.

Как уже отмечалось, использование TO_NUMBER () было бы лучшим выбором. +0 менее очевиден, чем явное приведение, и всегда хорошо иметь четкое представление о намерениях.

1 голос
/ 08 июля 2010

Есть ли индекс на TBL_CODE_ZIP.Code? Я видел запросы, которые добавляют 0 к числу (или '' к строке), чтобы заставить оптимизатор избегать использования индекса для этой части запроса. (Конечно, правильным способом избежать использования индекса является добавление соответствующей подсказки)

Возможно, у оригинального писателя была проблема, когда ORDER BY оптимизировался для сканирования индекса, что приводило к замедлению выполнения запроса; поэтому они добавили +0, чтобы вызвать другой путь доступа и выполнить обычную сортировку.

0 голосов
/ 20 марта 2012

Извините за ответ, потому что это очень старый вопрос.Однако +0 - это подсказка вашей базе данных, чтобы игнорировать индекс (если он находится в столбце a.Code) для этого конкретного запроса,

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

, так что теперь у вас есть две опции, например, используйте +0 подсказку или удалите индекс, если он на .code вы получите ту же скорость.

...