Форум программистов, компьютерный форум, киберфорум
Oracle
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.73/11: Рейтинг темы: голосов - 11, средняя оценка - 4.73
мну довольно <(-__-)l
216 / 205 / 15
Регистрация: 17.01.2010
Сообщений: 2,462
1

Oracle неправильно выполняет запрос или я неправильно принимаю Oracle

17.09.2013, 14:05. Показов 2247. Ответов 9

Неправильно отрабатывает автоматически сгенерированный NHibernate запрос.

T-SQL
1
2
3
4
5
6
7
8
select s.*, rownum from(
    select 
    t2.BOOLEAN_VALUE as c1
    from t1
    left outer join t2 on t1.REF1_ID=t2.ID 
    where t1.REF2_ID='3747FE8ACDA11547B5E456C1C4033C5B'
    order by t2.NAME asc, t1.ID asc 
) s
возвращает строки:
0 1
0 2
0 3


а должен возвращать то же что и этот запрос:
T-SQL
1
2
3
4
5
6
7
8
select s.* from(
    select 
    t2.BOOLEAN_VALUE as c1
    from t1
    left outer join t2 on t1.REF1_ID=t2.ID 
    where t1.REF2_ID='3747FE8ACDA11547B5E456C1C4033C5B'
    order by t2.NAME asc, t1.ID asc 
) s
то есть:
0 1
0 2
1 3


при этом если убрать rownum ответ правильный
если заменить left outer join на join - ответ правильный (но суть в том что запрос генерируется автоматически)
если убрать order - работает правильно


и на последок, запросы:
T-SQL
1
2
3
4
5
6
7
8
select s.* from(
    select 
    t2.BOOLEAN_VALUE as c1
    from t1
    left outer join t2 on t1.REF1_ID=t2.ID 
    where t1.REF2_ID='3747FE8ACDA11547B5E456C1C4033C5B'
    order by t2.NAME asc, t1.ID asc, t2.BOOLEAN_VALUE asc 
) s
T-SQL
1
2
3
4
5
6
7
8
select s.* from(
    select 
    t2.BOOLEAN_VALUE as c1
    from t1
    left outer join t2 on t1.REF1_ID=t2.ID 
    where t1.REF2_ID='3747FE8ACDA11547B5E456C1C4033C5B'
    order by t2.NAME asc, t1.ID asc, t2.BOOLEAN_VALUE desc 
) s
T-SQL
1
2
3
4
5
6
7
8
select s.* from(
    select 
    t2.BOOLEAN_VALUE as c1
    from t1
    left outer join t2 on t1.REF1_ID=t2.ID 
    where t1.REF2_ID='3747FE8ACDA11547B5E456C1C4033C5B'
    t2.BOOLEAN_VALUE asc 
) s
T-SQL
1
2
3
4
5
6
7
8
select s.* from(
    select 
    t2.BOOLEAN_VALUE as c1
    from t1
    left outer join t2 on t1.REF1_ID=t2.ID 
    where t1.REF2_ID='3747FE8ACDA11547B5E456C1C4033C5B'
    t2.BOOLEAN_VALUE desc 
) s
возвращают одно и тоже...
1 1
1 2
1 3


0_о
Как такое возможно?

Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64bit Production
PL/SQL Release 11.1.0.7.0 - Production
CORE 11.1.0.7.0 Production
TNS for 64-bit Windows: Version 11.1.0.7.0 - Production
NLSRTL Version 11.1.0.7.0 - Production
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
17.09.2013, 14:05
Ответы с готовыми решениями:

Delphi неправильно выполняет условия
Делаю простейшее условие: if nkv_0=0 then begin if n_0&gt;0 then updater; end else updater;...

Программа неправильно выполняет последнюю операцию деления
Почему программа не правильно выполняет последнюю операцию деления a4 / (-a3)? Нужна помощь!

Проверьте задачку по циклам, неправильно работает. [думаю что неправильно]
Спасибо что решили зайти. Задание выгладит так: http://*******/PW95p А результат выплнения:...

Неправильно работает цикл for, и функции работают неправильно
1) Неправильно работает цикл for(k=0...). Входит только 1 раз, дальше вылетает. Делал пошаговую...

9
Модератор
3920 / 2896 / 557
Регистрация: 21.01.2011
Сообщений: 12,550
17.09.2013, 14:38 2
Даже не знаю что сказать...

Во-первых, зачем эти все охватывающие запросы (кроме случая с rownum)?
Во-вторых, если достаточно inner join, зачем outer join? Поскольку в общем случае outer join работает медленее.
В-третьих, если можно без order by, то лучше обойтись без него (тоже добавляет работы).
Сказать, как должно быть правильно, не видя данных нереально.
Ссылки на автоматическую генерацию запросов не убедительны - никто не сказал, что генерируются оптимальные запросы.
Наконец никто не мешает сравнить планы запросов - может действительно оптимизатор Oracle где-то глючит, хотя и вряд ли.

PS
К слову сказать, ANSI-синтаксис join-ов появился только в Ora 9, содержал массу глюков, да и сейчас не свободен от них. Поэтому если есть сомнения в правильном выполнении запроса, до сих пор рекомендуют переписать запрос на "родной" синтаксис Oracle.

Добавлено через 5 минут
А люди, давно работающие с Oracle, практически этот самый ANSI-синтаксис не используют (большинство во всяком случае)
0
мну довольно <(-__-)l
216 / 205 / 15
Регистрация: 17.01.2010
Сообщений: 2,462
17.09.2013, 15:03  [ТС] 3
Цитата Сообщение от Grossmeister Посмотреть сообщение
на "родной" синтаксис Oracle.
а можно пруф на него? впервые слышу. да и с ораклом впервые работаю)

left потому что это ссылка в ORM на другую сущность. по правилам скорее всего null не будет, но только в этом конкретном случае. в других парах сущностей (М->1) может быть иначе...

оптимальность ни при чем. суть в том что результат неправильный, нареканий на скорость нет.

куда уж без order by, для пользователей же стараемся)

PS: пока решили отказаться от постраничного вывода. Пользователь больше 200 строк и не увидит и достаточно мало полей в них, так что не критично.

А вот если на поле повесить индекс, пусть даже на первые 10 символов. никакой просадкb производительности на order by и не будет...наверно, по крайней мере здесь, когда 10 первых символов уникальны? да и записей в t2 меньше 200...

Про карту и не вспомнил, взгляну...

Добавлено через 2 минуты
Цитата Сообщение от Grossmeister Посмотреть сообщение
Во-первых, зачем эти все охватывающие запросы (кроме случая с rownum)?
меня эта ситуация очень удивила, она еще страннее чем ситуация с group by когда требуется включить все поля в group by
T-SQL
1
select id, name from t group by t.id, t.name
вместо того как в мускуле
T-SQL
1
select id, name from t group by t.id
ORA-00979 выражение не является ввыражением group by
Добавлено через 2 минуты
Цитата Сообщение от Grossmeister Посмотреть сообщение
на "родной" синтаксис Oracle.
Цитата Сообщение от gGrn-7DA Посмотреть сообщение
а можно пруф на него?
Хотя nhibernate запрос из-за этого не перестроится...
0
Модератор
3920 / 2896 / 557
Регистрация: 21.01.2011
Сообщений: 12,550
17.09.2013, 15:15 4
Цитата Сообщение от gGrn-7DA
а можно пруф на него? впервые слышу. да и с ораклом впервые работаю)
Ну если никогда не работал с Oracle, неплохо бы ознакомится с синтаксисом его SQL. Либо по книжке, либо по доке (а лучше и то, и другое).
Если кратко:
SQL
1
2
3
4
5
6
7
8
9
10
11
12
-- inner join
SELECT *
FROM tab1 T1,
     tab2 T2
WHERE T1.id = T2.id
 
-- outer join
SELECT *
FROM tab1 T1,
     tab2 T2
WHERE T1.id = T2.id(+)
-- (+) с той стороны, где данных не хватает
Цитата Сообщение от gGrn-7DA
оптимальность ни при чем. суть в том что результат неправильный, нареканий на скорость нет.
Конечно неправильность хуже неоптимальности, но если запрос написан криво, то при увеличении объема данных скорость может и перестать устраивать

Цитата Сообщение от gGrn-7DA
А вот если на поле повесить индекс, пусть даже на первые 10 символов. никакой просадкb производительности на order by и не будет...наверно, по крайней мере здесь, когда 10 первых символов уникальны? да и записей в t2 меньше 200...
Индекс обычно влияет на скорость выборки строк, а не на сортировку. Во всяком случае, если в запросе больше 1 таблицы. Тем более, что оптимизатор сам выбирает путь выполнения.

Про карту и не вспомнил, взгляну...

Цитата Сообщение от gGrn-7DA
она еще страннее чем ситуация с group by когда требуется включить все поля в group by
T-SQL
1
select id, name from t group by t.id, t.name
вместо того как в мускуле
T-SQL
1
select id, name from t group by t.id
Обычно GROUP BY используется с агрегатными функциями типа COUNT, SUM и т.д. В этом случае действительно в GROUP BY требуется перечислить все поля, не входящие в групповую функцию. И это правильно, если хорошенько подумать. А то, что MySQL иногда допускает исключения из этого правила - так это виновать сам MySQL (использует некие умолчания).

Добавлено через 2 минуты
Цитата Сообщение от gGrn-7DA Посмотреть сообщение
Хотя nhibernate запрос из-за этого не перестроится...
Хех... А если это сгенерированный запрос не будет работать правильно, тогда что?

Не работал с Hibernate, но ни разу не видел автоматических построителей, которые генерировали нормальные запросы (кроме самых простейших случаев). Так что как чуть посложнее - сразу "ручной" режим
0
мну довольно <(-__-)l
216 / 205 / 15
Регистрация: 17.01.2010
Сообщений: 2,462
17.09.2013, 15:29  [ТС] 5
Цитата Сообщение от Grossmeister Посмотреть сообщение
(кроме самых простейших случаев)
вполне простой случай, всего то один join)
но да, если постраничный вывод засунуть до left outer join работать будет быстрее...
Цитата Сообщение от Grossmeister Посмотреть сообщение
Если кратко:
ооо, а я то думал, что так писать моветон)
Цитата Сообщение от Grossmeister Посмотреть сообщение
Так что как чуть посложнее - сразу "ручной" режим
Все так говрят...)
этот проект не позволит так, запросы через Linq строится. удобно очень..
Цитата Сообщение от Grossmeister Посмотреть сообщение
Индекс обычно влияет на скорость выборки строк, а не на сортировку. Во всяком случае, если в запросе больше 1 таблицы. Тем более, что оптимизатор сам выбирает путь выполнения.
для ускорения сортировки тоже индекс нужен.
Ты только подумай, при каждом select заново упорядочивать тонну значений? потому и проседает, раз без индекса)
Но хотя, не знаю что там в оракле, в мускуле так...))

Не по теме:

И вообще, почему oracle limit 0,20 не поддерживает? убивает эта вложенность с rownum(((



Добавлено через 6 минут
Цитата Сообщение от gGrn-7DA Посмотреть сообщение
потому и проседает, раз без индекса)
речь не о hash-table, а о Balansed+Tree
0
Модератор
3920 / 2896 / 557
Регистрация: 21.01.2011
Сообщений: 12,550
17.09.2013, 15:40 6
Цитата Сообщение от gGrn-7DA
Все так говрят...)
этот проект не позволит так, запросы через Linq строится. удобно очень..
Ну если сложных запросов на пару десятков таблиц или там с аналитикой не предполагается, то...
Хотя если я знаю БД, с которой работаю, то эти построители нафиг не нужны.

Цитата Сообщение от gGrn-7DA
для ускорения сортировки тоже индекс нужен.
Каким образом индекс по таблице может помочь для сортировки выборки хотя бы из 2-х таблиц? Как правило, в процессе построения выборки используются те или иные сортировки (хотя бы при nested loops). Если потом встречается еще и order by, то индекс тут уже никаким боком.

Цитата Сообщение от gGrn-7DA
И вообще, почему oracle limit 0,20 не поддерживает? убивает эта вложенность с rownum
LIMIT был введен в MySQL потому, что он изначально был ориентирован на Web, а там постраничный вывод встречается сплошь и рядом. А Oracle - для Enterprice, где подобные вещи используются редко.

Цитата Сообщение от gGrn-7DA
речь не о hash-table, а о Balansed+Tree
Ты все таки почитай про Oracle, хотя бы том доки Concepts. А то используешь термины из другой СУБД, которые в Oracle не применяются.
0
мну довольно <(-__-)l
216 / 205 / 15
Регистрация: 17.01.2010
Сообщений: 2,462
17.09.2013, 15:56  [ТС] 7
Цитата Сообщение от Grossmeister Посмотреть сообщение
Хотя если я знаю БД, с которой работаю, то эти построители нафиг не нужны.
к сожалению приходится думать о тех, кто придет после нас. да и вдруг что поменяется...
Цитата Сообщение от Grossmeister Посмотреть сообщение
nested loops
это какая-то экзотика? по нему позже отвечу.
Цитата Сообщение от Grossmeister Посмотреть сообщение
Каким образом индекс по таблице может помочь для сортировки выборки хотя бы из 2-х таблиц?
если сортировка по t1.name поможет. а вот если order by NVL(t1.name, t2.name) то да, все плохо.
Хотя вычисляемые выражения в order by совать не рекомендуют.
то есть
здесь индекс(B+Tree) полезен
T-SQL
1
select t1.*,t2.* from t1 join t2 on t1.col1=t2.col13 order by t1.name
тут бесполезен. ибо вычисляемое значение используется
T-SQL
1
select t1.*,t2.* from t1 join t2 on t1.col1=t2.col13 order by NVL(t1.name,t2.name)
та же история с COALESCE и ISNULL...

а про nested loops тоже почитаю...

Добавлено через 1 минуту
не спутай Balansed Tree и Balanced+ Tree )

Добавлено через 1 минуту
Цитата Сообщение от Grossmeister Посмотреть сообщение
LIMIT был введен в MySQL потому, что он изначально был ориентирован на Web, а там постраничный вывод встречается сплошь и рядом. А Oracle - для Enterprice, где подобные вещи используются редко.
вот только этот limit не такой и сложный наверно. Oracle давно уже могла бы и научиться самостоятельно разворачивать limit в rownum :-\
0
Модератор
3920 / 2896 / 557
Регистрация: 21.01.2011
Сообщений: 12,550
17.09.2013, 16:19 8
Цитата Сообщение от gGrn-7DA
к сожалению приходится думать о тех, кто придет после нас. да и вдруг что поменяется...
Еще раз повторюсь - в сложных запросах автоматика не помошник

Цитата Сообщение от gGrn-7DA
это какая-то экзотика? по нему позже отвечу.
nested loops - один из основных методов соединения строк таблиц в выборках

Цитата Сообщение от gGrn-7DA
если сортировка по t1.name поможет.
С MySQL работал мало, поэтому сказать затрудняюсь. В Oracle индекс для таких вещей не используется

Цитата Сообщение от gGrn-7DA
не спутай Balansed Tree и Balanced+ Tree )
В Oracle есть просто B-Tree индексы. Поэтому путать не придется.
Правда еще есть bitmap-индексы, reverse, FBI (function-based) и некоторые другие.

Цитата Сообщение от gGrn-7DA
вот только этот limit не такой и сложный наверно. Oracle давно уже могла бы и научиться самостоятельно разворачивать limit в rownum :-\
Видимо они считают, что это используется редко. А все редкие хотелки пользователей не реализуешь...
0
мну довольно <(-__-)l
216 / 205 / 15
Регистрация: 17.01.2010
Сообщений: 2,462
17.09.2013, 16:54  [ТС] 9
Вернемся к первоначальному вопросу. Почему оно работает неправильно?)
К сожалению исправить на ручной запрос не удастся...не предусмотрено ахритектурой.
0
Модератор
3920 / 2896 / 557
Регистрация: 21.01.2011
Сообщений: 12,550
17.09.2013, 17:15 10
Цитата Сообщение от gGrn-7DA Посмотреть сообщение
Вернемся к первоначальному вопросу. Почему оно работает неправильно?
Собственно, все предположения я уже высказал:
1. на самом деле работает правильно (без данных сказать не представляется возможным)
2. глюк из-за синтаксиса ANSI
3. глюк оптимизатора (здесь только смотреть планы выполнения)

А вообще в Oracle принято, что истина в последней инстанции - выполнение запроса в SQL*Plus. Если он там работает правильно, а в каком-то ГУИ или в клиентской программе неправильно - виноват не Oracle (не сервер).
Если и там неправильно - тогда это возможный глюк, надо заводить SR (Service Request) на Металинке (если, разумеется, куплена лицензия), или же изменять запрос (workaround). Поэтому я бы начал с запуска этих запросов в SQL*Plus
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.09.2013, 17:15

Какими средствами Oracle экспортировать данные из таблицы Oracle в dbf-файл?
Здравствуйте! Не подскажите чайнику какими средствами Oracle экспортировать данные из таблицы...

Соединение к Oracle 11g XE из сервера приложений Oracle Weblogic Server 10.3.5.0
здравствуйте уважаемые форумчане! не знаю к какому разделу подходит эта тема но все равно.... :)...

Ошибка подключения к базе Oracle DB Express 11g через Oracle Data Integrator
Приветствую. На работе дали задание: установить Oracle Data Integrator и создать стенд с...

Как устранить ошибку [Microsoft][ODBC driver for oracle][Oracle]ORA-20003
При работе в программе возникает вот такая ошибка ORA-20003 что это может быть?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru