Что +0 означает после ORDER BY в Oracle

Я пытаюсь понять то, что +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. Код и +0 и я могу добавить asc или desc после +0

9
задан Lucas B 7 July 2010 в 16:15
поделиться

4 ответа

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

По вашему запросу, единственный вывод, который я могу сделать после его изучения, это то, что его создатель боролся с производительностью. Если (это мое предположение) индекс CODE_ZIP_CODE_IX является индексом для TBL_CODE_ZIP (Code), то запрос не будет его использовать, даже если он намекнул на его использование. Создатель, вероятно, не знал, что, используя 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') или любого другого выражения, которое вы используете для левой панели вашего почтового индекса.

8
ответ дан 4 December 2019 в 11:03
поделиться

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


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

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 менее очевидно, чем явное приведение, а всегда полезно уточнять намерения.

3
ответ дан 4 December 2019 в 11:03
поделиться

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

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

7
ответ дан 4 December 2019 в 11:03
поделиться

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

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

1
ответ дан 4 December 2019 в 11:03
поделиться
Другие вопросы по тегам:

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