powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Помогите с запросом
8 сообщений из 33, страница 2 из 2
Помогите с запросом
    #33685455
Владимор Конев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ASCRUSВот при JOIN/EXISTS/IN как раз выборка и посадится на INDEX SCAN, а WHERE CASE уйдет на TABLE SCAN и использовать индексы оптимизатор не будет. Это кстати насколько я понимаю, не только к ASA относится, но и любому РСУБД - хотел бы я увидеть сервер, который Ваш последний запрос на индексы подсадит для фильтрации по нужным условиям.Никто не мешает развернуть CASE в обычное (AND ... OR) условие, котооре также легко посадится на индекс.

А в остальном - согласен...
...
Рейтинг: 0 / 0
Помогите с запросом
    #33685711
iLLer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владимор КоневНикто не мешает развернуть CASE в обычное (AND ... OR) условие, котооре также легко посадится на индекс.
В том то и дело, что не развернете. Это все равно что делать условие на результат функции, типа такого: WHERE trim(data)='конкретная строка', тут индекс по data не поможет.
Ваш запрос, применительно к ситуации:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
select *
from
          (select t2.tovar_id , 
                 sum(case
                        when (t2.spell_word_id= 430084  and t2.flag_locate= 1 )
                             or
                             (t2.spell_word_id= 430881  and t2.flag_locate= 1 )
                        then  1 
                        else  0 
                     end) 
                 over(partition by tovar_id) as cnt
            from tovar_spell_words as t2) as v(i,c)
 where c =  2 
( Plan [ Total Cost Estimate: 18.08553618 ]
( WorkTable
( Filter [ expr( 1, 0, t2.spell_word_id, t2.flag_locate ) = 2 : 5% Guess ]
( Window
( IndexScan ( tovar_spell_words t2 ) tovar_fk )
)
)
)
)
Анализируем план: Первая ступень, скаинрование индекса по tovar_id, только не на конкретное значение, а ВСЕГО, из него делает окна по общим значениям, применяет условия поиска, фильтрует лишнее, и все это делалось во временной таблице, которая в основном будет лежать в "файле подкачки" asa_temp. Явно быстродействием такой подход не блещет, потому что напрямую зависит от объема индекса, таблицы (зависимость вроде квардратичная получается).
Как видно подходов масса, результат выборок один, а планы принципиально разные.
...
Рейтинг: 0 / 0
Помогите с запросом
    #33685722
iLLer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, и еще, OLAP функции нужны для статистической обработки как можно большего массива данных, и чем больше, тем больше выигрыш от их применения. А делать анализ всей таблицы для поиска нескольких значений - это абсолютно неправильно, для этого есть индексы и правильная организация хранения данных.
...
Рейтинг: 0 / 0
Помогите с запросом
    #33685747
Владимор Конев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iLLer Владимор КоневНикто не мешает развернуть CASE в обычное (AND ... OR) условие, котооре также легко посадится на индекс.
В том то и дело, что не развернете.Если честно, то я в упор не увидел в анализируемом тобой варианте каких-то бы ни было условий фильтрации во внутреннем подзапросе...

Я же предлагал делать примерно так:
1) Выбрать по условию часть записей из таблицы, удовлетворяющих тому, что написано в CASE, только при этом развернуть CASE в обычные AND/OR - условия (что бы индексы можно было заюзать)
2) Наложить на полученный результат аналитическую функцию
3) Обернуть полученное и отфильтровать по условию, удовлетворяющему поставленной задаче.
Ну где-то вот так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
select * 
  from (
          select t.* , 
                 sum(case
                        when property_id = '0006' and propertyvalue = 'red'
                             or
                             property_id = '0007' and propertyvalue = '10x10'
                        then  1 
                        else  0 
                     end) 
                 over(partition by good_id) as cnt
            from t
           where property_id = '0006' and propertyvalue = 'red'
                 or
                 property_id = '0007' and propertyvalue = '10x10'
        )
 where cnt =  2 
...
Рейтинг: 0 / 0
Помогите с запросом
    #33685789
Фотография ASCRUS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тогда уж правильнее:
Код: plaintext
where property_id in ('0006', '0007')
где если будет индекс на property_id, он задействуется, а далее все равно будет скан всех записей и вместо фильтра (value = ...), это обработается в CASE (таким образом не будет дважды делать одну и ту же работу). Другое дело, что аналитические функции все равно здесь не пригодятся - они хороши, когда нужно посчитать некие значения на последовательности записи (к примеру нарастающие итоге) - здесь же будет уместнее сделать обычный Sum(case ...) AS cnt где HAVING cnt = 2.
--
www.rusug.ru - портал русскоязычной группы пользователей Sybase
...
Рейтинг: 0 / 0
Помогите с запросом
    #33685817
iLLer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ничего принципиального не изменилось:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
select *
from
          (select t2.tovar_id , 
                 sum(case
                        when (t2.spell_word_id= 430084  and t2.flag_locate= 1 )
                             or
                             (t2.spell_word_id= 430881  and t2.flag_locate= 1 )
                        then  1 
                        else  0 
                     end) 
                 over(partition by tovar_id) as cnt
            from tovar_spell_words as t2
            where (t2.spell_word_id= 430084  and t2.flag_locate= 1 )
                             or
                         (t2.spell_word_id= 430881  and t2.flag_locate= 1 )) as v(i,c)
 where c =  2 ;
Тот же индекс по товарам, тоже сканирование, только дополнительное уменьшение обрабатываемого объема:
( Plan [ Total Cost Estimate: 18.08577018 ]
( WorkTable
( Filter [ expr( 1, 0, t2.spell_word_id, t2.flag_locate ) = 2 : 5% Guess ]
( Window
( IndexScan ( tovar_spell_words t2 ) tovar_fk[ ( t2.spell_word_id IN ( 430084, 430881 ) : 4.692411795% Statistics ) AND ( t2.flag_locate = 1 : 100% Statistics ) ] )
)
)
)
)
Согласен с ASCRUS. Операция OR вносит свою лепту, либо отказываемся от индекса по значениям, либо свойствам. Вообщем, думаю что уже ясно, что OLAP не сюда.
...
Рейтинг: 0 / 0
Помогите с запросом
    #33685903
Владимор Конев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 iLLer, ASCRUS.
ОК, уболтали...
Я сам с ASA просто никогда не работал, так что верю вам на слово :)
...
Рейтинг: 0 / 0
Помогите с запросом
    #33686027
Фотография ASCRUS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не думаю, что в Оракле ситуация будет чем то другая - во всяком случае на моей памяти для 9-ой версии поведение оптимизатора будет похожим :)
--
www.rusug.ru - портал русскоязычной группы пользователей Sybase
...
Рейтинг: 0 / 0
8 сообщений из 33, страница 2 из 2
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Помогите с запросом
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]