powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Как происходит умножение таблиц ???
23 сообщений из 23, страница 1 из 1
Как происходит умножение таблиц ???
    #34743801
--__Александр__--
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Версия Sybase 12.5.1
Собственно вопрос, как происходит умножение??? ))
select a.table1,z.table2
from table1,table2
where a.table1=v.table2
Сначала генерируеться декартово произведение таблиц, а потом к полученной таблице применяеться условие? Или как-то подругому ???

И еще один пример:
select a.table1,z.table2
from table1,table2
where a.table1=v.table2
and b.table1 = 1234

Здесь такой же вопрос, сначала произведение генерируеться,а потом накладываеться условие
или допустим в произведение участвуют только те строки из тоблицы table1, которые удовлетворяют условию b.table1 = 1234, а потом уже идет произведение по связке a.table1=v.table2 ???

А когда в произведение участвует допустим 3 таблицы, причем количество строк в
table1 = 1 000 000 000, table2 = 1 000 000 000, table3 = 200
select ...... .....
from table1,
table2,
table3
where a.table1= v.table2
and x.table2= p.table3

Можно ли как-то построить этот запрос, чтоб он выполнялся максимально быстро.
Или его лучше разбить? Сначала перемножить table2 на table3 во временную таблицу, а потом уже полученный результат умножить на таблицу table1.
...
Рейтинг: 0 / 0
Как происходит умножение таблиц ???
    #34743888
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
--__Александр__-- пишет:
> Собственно вопрос, как происходит умножение??? ))
> select a.table1,z.table2
> from table1,table2
> where a.table1=v.table2
> Сначала генерируеться декартово произведение таблиц, а потом к
> полученной таблице применяеться условие? Или как-то подругому ???

Можешь считать, что так. Для результата это совершенно все равно.
На самом деле какой-то конкретный алгоритм выполнения операций
в SQL вообще не определен - есть только декларативные правила.

> Можно ли как-то построить этот запрос, чтоб он выполнялся максимально
> быстро.
> Или его лучше разбить? Сначала перемножить table2 на table3 во временную
> таблицу, а потом уже полученный результат умножить на таблицу table1.

На первом этапе об этом думать не надо. Это - задача оптимизатора
запросов, который должен выработать план выполнения запроса так,
чтобы он был оптимальным.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Как происходит умножение таблиц ???
    #34743963
--__Александр__--
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мляяя, для результата конечно все равно )) Меня волнует вопрос производительности(скорости выполнения).
Перемножить две таблицы в которых количество записей порядка милиарда - это уже существенное время, а потом еще производить сканирование полученного произведения для применения условия WHERE - еще время.
Я так понял явно указать оптимизатору, что бы он выполнял сначала сканирование таблицы 1 для применения условия b.table1 = 1234, потом полученную усеченную таблицу умножал на таблицу 2 и потом уже применял условие a.table1=v.table2 НЕЛЬЗЯ ????
Единственный выход для этого - применять промежуточные таблицы??? Но это как-то некрасиво что ли ))
...
Рейтинг: 0 / 0
Как происходит умножение таблиц ???
    #34743997
teras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
--__Александр__--Сначала генерируеться декартово произведение таблиц, а потом к полученной таблице применяеться условие? Или как-то подругому ??? Если вас этот вопрос интересует с точки зрения производительности, то нет, так не делается. Даже если нет индексов, что выполняется сканирование таблицы, на которую наложено условие, и вложенным циклом сканируется вторая, третья и т.д. таблицы, для генерации произведения в оптимальном пространстве за оптимальное время.

--__Александр__--А когда в произведение участвует допустим 3 таблицы, причем количество строк в
table1 = 1 000 000 000, table2 = 1 000 000 000, table3 = 200
select ...... .....
from table1,
table2,
table3
where a.table1= v.table2
and x.table2= p.table3

Можно ли как-то построить этот запрос, чтоб он выполнялся максимально быстро.
Или его лучше разбить? Сначала перемножить table2 на table3 во временную таблицу, а потом уже полученный результат умножить на таблицу table1. Вообще, лучше всего использовать индексы. Но если их нельзя использовать или в результате все равно получается декартово произведение, то... Не скажу, как в Sybase 12, не пользую, но если он собирает статистику селективности, то лучше оставить это дело оптимизатору, если нет (только cost based оптимизация), то перечисляйте условия в порядке максимального сокращения количества записей, или используйте подсказки оптимизатору.
...
Рейтинг: 0 / 0
Как происходит умножение таблиц ???
    #34744395
москит
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
--__Александр__--Версия Sybase 12.5.1
Собственно вопрос, как происходит умножение??? ))
select a.table1,z.table2
from table1,table2
where a.table1=v.table2
Сначала генерируеться декартово произведение таблиц, а потом к полученной таблице применяеться условие? Или как-то подругому ???

Надеюсь запрос всё-таки выглядит так:
Код: plaintext
1.
2.
select * -- что возвращается, не так важно
    from table1,table2
   where table1.a=table2.b

Возможны следующие варианты:
1) Индексов по table1.a и table2.b нет. table scan + loop join + tablescan.
Выбирается таблица, которая будет первой в плане выполнения запроса.
Для неё выбирается стратегия выборки table scan и осуществляется полное сканирование таблицы.
При чтении каждой записи первой таблицы выполняется полное сканирование второй. На каждое удачное присоединение второй формируется строка результата и отправляется клиенту(на самом деле не по одной, а пачками, но отправка клиенту части результата может производится раньше, чем запрос выполнится полностью).
2) По table1.a и table2.b есть один индекс, второго нет. table scan + loop join + index seek.
Аналогично, первому случаю, но первой выбирается таблица без индекса, а строки второй таблицы, которые соответсвуют первой по условию выбираются за счет индекса, т.е. строки не удовлетворяющие не перебираются, как в первом случае.
3) Оба индекса есть. Либо merge join по индексам, либо как во-втором, но первой скорее всего окажется таблица, которая меньше.

--__Александр__--
И еще один пример:
select a.table1,z.table2
from table1,table2
where a.table1=v.table2
and b.table1 = 1234

Здесь такой же вопрос, сначала произведение генерируеться,а потом накладываеться условие
или допустим в произведение участвуют только те строки из тоблицы table1, которые удовлетворяют условию b.table1 = 1234, а потом уже идет произведение по связке a.table1=v.table2 ???

Оптимизатор, если ему не подсказывать, сам выберет то, что посчитает быстрее. Может начать с отбором по условию, а потом делать присоединение другой таблицы, может наоборот, сначала соединять, потом не включать в результат, что не подошло по условию.

--__Александр__--
А когда в произведение участвует допустим 3 таблицы, причем количество строк в
table1 = 1 000 000 000, table2 = 1 000 000 000, table3 = 200
select ...... .....
from table1,
table2,
table3
where a.table1= v.table2
and x.table2= p.table3

Можно ли как-то построить этот запрос, чтоб он выполнялся максимально быстро.
Или его лучше разбить? Сначала перемножить table2 на table3 во временную таблицу, а потом уже полученный результат умножить на таблицу table1.
Для того, чтоб запросы работали быстро на больших таблицах, надо:
1) Создавать индексы
2) Клиетское приложение должно предоставлять пользователю только малую часть данных, за счет ограничений(фильтров), которые он задаст. Пользователю не нужно видеть милионов записей, он их не то что не "прочитает", но и даже пролистать сможет с трудом. Например, работая с грамотным приложением, можно получить сообщение "Вы искали: bla-bla-bla, найдено сайтов: 15709, документов: 162764, новых: 328", но при этом всей информации(162764) отобразится только 15, и то в качестве ссылок.
...
Рейтинг: 0 / 0
Как происходит умножение таблиц ???
    #34744615
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
> Я так понял явно указать оптимизатору, что бы он выполнял сначала
> сканирование таблицы 1 для применения условия b.table1 = 1234, потом
> полученную усеченную таблицу умножал на таблицу 2 и потом уже применял
> условие a.table1=v.table2 НЕЛЬЗЯ ????

Можно. Хинтами оптимизатора, абстрактными планами.

> Единственный выход для этого - применять промежуточные таблицы??? Но это

Нет, это вообще не выход. Будет только хуже.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Как происходит умножение таблиц ???
    #34744633
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
москит пишет:

> 3) Оба индекса есть. Либо merge join по индексам, либо как во-втором, но
> первой скорее всего окажется таблица, которая меньше.

Sort merge join может и если вообще нет индексов, он их сам может построить
(что тоже ст`оит в смысле IO, естественно).
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Как происходит умножение таблиц ???
    #34745140
--__Александр__--
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так, напишу что получилось )))
Было такой кусок :
insert into admin_hierarchy_week
select distinct 252,
bat.battalion_name,
bat.sadmin_name,
isnull( bat.admin_name, cdr.bidl ),
isnull( bat.departament_name, '' ),
isnull( convert( int, cdr.emp_tablenum ), convert( int, ptcp.tabel )),
isnull( cdr.emp_lastname, client.descr ) + ' ' + cdr.emp_firstname,
isnull( cdr.emp_personcode, -13 ),
ptcp.mng_bank_id,
cdr.bidl,null
from
dwh_stg..fr_ptcp_hist_adr ptcp,
front_common..f_client client,
dwh_stg..cdr_employee cdr,
dwh_stg..cdr_bat_oe_week bat
where
and ptcp.bank_id = 252
and '08/20/07' between ptcp.begin_date and isnull(ptcp.end_date,'08/20/07')
and ptcp.f_manager_id = client.f_client
and convert( int, ptcp.tabel ) *= convert( int, cdr.emp_tablenum )
and datediff( mm, isnull( cdr.emp_dismissdate, '08/20/07' ), '08/20/07' ) <= 1
and cdr.bidl *= bat.bid
and cdr.emp_oe1_id <> 2094

В таблице fr_ptcp_hist_adr - 4 000 000 записей,f_client - 750 000,cdr_employee - 5000
cdr_bat_oe_week - 300 записей.
Индексы в fr_ptcp_hist_adr и f_client "все" есть )) В admin_hierarchy_week соответсвенно нету.

Этот инсерт работал больше часа.

Я этот кусок разбил на :
create table #tmp_af_adm_her
(
bank_id int NULL,
f_manager_id int NULL,
tabel int NULL,
mng_bank_id int NULL
)

insert into #tmp_af_adm_her
select distinct ptcp.bank_id,ptcp.f_manager_id,convert( int, ptcp.tabel ),mng_bank_id
from dwh_stg..fr_ptcp_hist_adr ptcp
where ptcp.bank_id = 252
and '08/20/07' between ptcp.begin_date and isnull(ptcp.end_date,'08/20/07')
плюс
insert into tmp_af_admin_hierarchy_week_2
select distinct 252,
bat.battalion_name,
bat.sadmin_name,
isnull( bat.admin_name, cdr.bidl ),
isnull( bat.departament_name, '' ),
isnull( convert( int, cdr.emp_tablenum ), convert( int, ptcp.tabel )),
isnull( cdr.emp_lastname, client.descr ) + ' ' + cdr.emp_firstname,
isnull( cdr.emp_personcode, -13 ),
ptcp.mng_bank_id,
cdr.bidl,null
from
#tmp_af_adm_her ptcp,
front_common..f_client client,
dwh_stg..cdr_employee cdr,
dwh_stg..cdr_bat_oe_week bat
where cdr.bidl *= bat.bid
and ptcp.f_manager_id = client.f_client
and convert( int, ptcp.tabel ) *= convert( int, cdr.emp_tablenum )
and datediff( mm, isnull( cdr.emp_dismissdate, '08/20/07' ), '08/20/07' ) <= 1
and cdr.emp_oe1_id <> 2094

Теперь это работает 3 минуты. Результат на лицо )))
Просто все дело в том, что после наложения условия на fr_ptcp_hist_adr в #tmp_af_adm_her попадает всего 1000 записей. Как раз 3 минуты и уходят на эту вставку. Все остальное выполняеться мгновенно.

Теперь напишите пожалуйста, как указать оптимизатору в первом варианет запроса что бы он сначала отсекал все ненужное от fr_ptcp_hist_adr, а потом уже выполнял остальные перемножения???
Версия сайбс ASE 12.5.1 . Тока напишите конкретно, а не как в общем )))
...
Рейтинг: 0 / 0
Как происходит умножение таблиц ???
    #34745763
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
--__Александр__-- пишет:

> Теперь напишите пожалуйста, как указать оптимизатору в первом варианет
> запроса что бы он сначала отсекал все ненужное от fr_ptcp_hist_adr, а
> потом уже выполнял остальные перемножения???

Например так :

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
set showplan on
go

set forceplan on
go

set noexec on
go

insert into admin_hierarchy_week
select distinct  252 ,
  bat.battalion_name,
  bat.sadmin_name,
  isnull( bat.admin_name, cdr.bidl ),
  isnull( bat.departament_name, '' ),
  isnull( convert( int, cdr.emp_tablenum ), convert( int, ptcp.tabel )),
  isnull( cdr.emp_lastname, client.descr ) + ' ' + cdr.emp_firstname,
  isnull( cdr.emp_personcode, - 13  ),
  ptcp.mng_bank_id,
  cdr.bidl,null
from
  dwh_stg..fr_ptcp_hist_adr ptcp,
  front_common..f_client client,
  dwh_stg..cdr_employee cdr,
  dwh_stg..cdr_bat_oe_week bat
where ptcp.bank_id =  252 
  and '08/20/07' between ptcp.begin_date and isnull(ptcp.end_date,'08/20/07')
  and ptcp.f_manager_id = client.f_client
  and convert( int, ptcp.tabel ) *= convert( int, cdr.emp_tablenum )
  and datediff( mm, isnull( cdr.emp_dismissdate, '08/20/07' ), '08/20/07'
  ) <=  1 
  and cdr.bidl *= bat.bid
  and cdr.emp_oe1_id <>  2094 

set noexec off
go

set showplan off
go

set forceplan off
go


Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Как происходит умножение таблиц ???
    #34745767
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
--__Александр__-- пишет:

Но вообще запрос плохой, не гарантирую, что с форспланом
он будет быстро скакать.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Как происходит умножение таблиц ???
    #34746040
--__Александр__--
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
)) Ыыы. Запрос плохой )) Чем богаты, тем и рады. Буду блогадарен, если скажите, чем плохо???
И буду благодарен еще больше, если поправите ))

З.Ы. А как вы так красиво встовляете куски кода, а то у меня бардак вставился(все отступы пропали (( )

Спасибо, теперь буду хоть знать, что надо рыть инфу по использованию форсплана )).
...
Рейтинг: 0 / 0
Как происходит умножение таблиц ???
    #34746187
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
--__Александр__-- пишет:
> Автор: "--__Александр__--"
> )) Ыыы. Запрос плохой )) Чем богаты, тем и рады. Буду блогадарен, если
> скажите, чем плохо???

Использованием функций. Но на самом деле ты даешь мало информации
для размышления, надо знать всю твою БД, чтобы что-то говорить,
можно ли там сделать что-то лучше.

Приведи DDL тавблиц, индексов, и частотность вхождения
всех полей, которые в запросах используются. тогда можно
будет что-то более подробно сказать про твой запрос.

На вскидку, но не обязательно верно, плохо следующее :


select distinct .. вместо select ... . Обычно если БД
нормально спроектирована, DISTINCT не нужен в 80% случаев.
А это - сортировка результирующего набора.


and \'08/20/07\' between ptcp.begin_date and isnull(ptcp.end_date,\'08/20/07\')
Плохое условие. На самом деле эквивалентно двум

\'08/20/07\' between ptcp.begin_date and ptcp.end_date
or \'08/20/07\' > ptcp.begin_date and ptcp.end_date is null

Лучше бы использовать второй вариант.

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


Следующее - вообще убийственный для любого запроса вариант.
JOIN по выражению. Индекс никогда не будет использоваться :

and convert( int, ptcp.tabel ) *= convert( int, cdr.emp_tablenum )

Это надо убирать 100%.




and datediff( mm, isnull( cdr.emp_dismissdate, \'08/20/07\' ), \'08/20/07\'
) <= 1



> З.Ы. А как вы так красиво встовляете куски кода, а то у меня бардак
> вставился(все отступы пропали (( )

Тег "SRC". Вообще почитайте в FAQ по форуму тему "как оформлять сообщения".

> Спасибо, теперь буду хоть знать, что надо рыть инфу по использованию
> форсплана )).

На самом деле лучше его не использовать. Очень опасная штука, потому
что очень мощная. Это как отбойный молоток - стенку снесет, но вот
гравировать им неудобно.

может так все же лучше ?

Код: plaintext
\n\nselect ...\nfrom dwh_stg..fr_ptcp_hist_adr ptcp\njoin front_common..f_client client on ptcp.f_manager_id = client.f_client\nleft join dwh_stg..cdr_employee cdr on convert( int, ptcp.tabel ) = convert( \nint, cdr.emp_tablenum )\n-- должно быть ptcp.tabel = cdr.emp_tablenum\nleft join dwh_stg..cdr_bat_oe_week bat on cdr.bidl = bat.bid\nwhere ptcp.bank_id =  252 \n   and \'08/20/07\' between ptcp.begin_date and isnull(ptcp.end_date,\'08/20/07\')\n   and datediff( mm, isnull( cdr.emp_dismissdate, \'08/20/07\' ), \'08/20/07\' ) <=  1 \n   and cdr.emp_oe1_id <>  2094 \n

Итого имеем запрос об ОДНОМ SARG-ге - "ptcp.bank_id = 252".
Не думаю, что он очень селективен.
Ну и что вы хотите от такого запроса, чтобы он быстро работал ?


Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Как происходит умножение таблиц ???
    #34746294
москит
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
from
  dwh_stg..fr_ptcp_hist_adr ptcp,
  front_common..f_client client,
  dwh_stg..cdr_employee cdr,
  dwh_stg..cdr_bat_oe_week bat
where ptcp.bank_id =  252 
/*1*/  and '08/20/07' between ptcp.begin_date and isnull(ptcp.end_date,'08/20/07')
/*2*/  and ptcp.f_manager_id = client.f_client
/*3*/  and convert( int, ptcp.tabel ) *= convert( int, cdr.emp_tablenum )
/*4*/  and datediff( mm, isnull( cdr.emp_dismissdate, '08/20/07' ), '08/20/07') <=  1 
/*5*/  and cdr.bidl *= bat.bid
         and cdr.emp_oe1_id <>  2094 

А теперь по пунктам.
Судя по всему, с порядком таблиц всё нормально, так что можно ставиить forceplan.
/*1*/ Если есть индекс на fr_ptcp_hist_adr начинающинающийся с end_date или bank_id и end_date, то указываем этот индекс и переписываем условие присоединения на
Код: plaintext
and isnull(ptcp.end_date,'20070820') >= '20070820' and ptcp.begin_date <= '20070820'
а теперь разделяем условия заменяя
Код: plaintext
isnull(ptcp.end_date,'20070820') >= '20070820'
на
Код: plaintext
ptcp.end_date >= '20070820'
и через union all дублируем запрос с условием
Код: plaintext
ptcp.end_date is null
.
/*2*/ Если есть индекс на f_client по f_client то ставим его.
/*3*/ А зачем конвертация ? Не знаю, из каких типов и какие значения конвертятся(может из varchar с пробеламми вначале строки), но если замена условия на
Код: plaintext
cdr.emp_tablenum =* convert(<тип cdr.emp_tablenum>, ptcp.tabel)
и это будет работать "корректно", то надо условие заменить.
/*4*/ Опять пытаемся кого-то запутать? Оптимизатор или тех, кому этот код достанется ?
Код: plaintext
(cdr.emp_dismissdate is null or cdr.emp_dismissdate >= '20070701' /*начало прошлого месяца*/)
/*5*/ Индекс по cdr_bat_oe_week.bid есть ? Если есть то ставим его!
...
Рейтинг: 0 / 0
Как происходит умножение таблиц ???
    #34746305
--__Александр__--
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
)) СПС. Принял инфу к размышлению. На утреннюю голову сразу такой вопрос:
Практика показала, что произведение/сравнение по текстовому полю идет намного дольше, чем по числовому.
База спроектирована не мной, но уж такая фигня, что поля ptcp.tabel и cdr.emp_tablenum являеться чаровскими, но в них храниться числовая айдишка (вот такой вот нонсенс). Поэтому и стоит конверт. Казалдось, что так будет быстрее.
Второе, что я понял, лучше дистинкт убрать, а потом просто на задвоенность проверить. Но это гемор. Автоматизировать проверку задвоеености и удаление лишний строки - не так просто.

Про битвин ясно. А вот дэйтдиф чем не понравился??? Его убрать нельзя )) Условие важное ))).
З.Ы. От этого запроса уже ничего больше нехочу. Разбил его на два и теперь все летает. Хочу научиться прогать правильно )).
...
Рейтинг: 0 / 0
Как происходит умножение таблиц ???
    #34746437
--__Александр__--
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Этот код мне достался )) А вот пытаюсь его в божеский вид привести. СПС, щас буду размышлять над тем, что вы мне понаписали и тестить )) Еще раз огромное спасибо.
...
Рейтинг: 0 / 0
Как происходит умножение таблиц ???
    #34748939
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
--__Александр__-- пишет:
> Практика показала, что произведение/сравнение по текстовому полю идет
> намного дольше, чем по числовому.

Ерунда полная.

> cdr.emp_tablenum являеться чаровскими, но в них храниться числовая
> айдишка (вот такой вот нонсенс). Поэтому и стоит конверт. Казалдось, что

Нет, будет медлееннее. Убирай.

> Второе, что я понял, лучше дистинкт убрать, а потом просто на
> задвоенность проверить. Но это гемор. Автоматизировать проверку
> задвоеености и удаление лишний строки - не так просто.

Да наверняка там не может быть в принципе дублирующих строк.
Просто надо знать свою БД

> Про битвин ясно. А вот дэйтдиф чем не понравился??? Его убрать нельзя ))
> Условие важное ))).

На between его что не заменить никак ?
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Как происходит умножение таблиц ???
    #34749565
москит
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
--__Александр__--
З.Ы. От этого запроса уже ничего больше нехочу. Разбил его на два и теперь все летает. Хочу научиться прогать правильно )).

Покажи, как разбил. И план получившегося.
...
Рейтинг: 0 / 0
Как происходит умножение таблиц ???
    #34749936
--__Александр__--
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Было вот что:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
insert into admin_hierarchy
select distinct  252 , 
                   bat.battalion_name, 
                   bat.sadmin_name, 
                   isnull( bat.admin_name, cdr.bidl ), 
                   isnull( bat.departament_name, '' ), 
                   isnull( convert( int, cdr.emp_tablenum ), convert( int, ptcp.tabel )), 
                   isnull( cdr.emp_lastname, client.descr ) + ' ' + cdr.emp_firstname, 
                   isnull( cdr.emp_personcode, - 13  ), 
                   ptcp.mng_bank_id,
                   cdr.bidl,null 
   from 
         dwh_stg..fr_ptcp_hist_adr ptcp,
         front_common..f_client client,
         dwh_stg..cdr_employee cdr,
         dwh_stg..cdr_bat_oe_week bat
   where ptcp.bank_id =  252 
      and @last_dated between ptcp.begin_date and isnull(ptcp.end_date,@last_dated)
      and ptcp.f_manager_id = client.f_client
      and convert( int, ptcp.tabel ) *= convert( int, cdr.emp_tablenum )
      and datediff( mm, isnull( cdr.emp_dismissdate, @last_dated), @last_dated) <=  1 
      and cdr.bidl *= bat.bid 
      and cdr.emp_oe1_id <>  2094 
а теперь
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
        create table #tmp_af_adm_her
        (
            bank_id          int        NULL,
            f_manager_id  int        NULL,
            tabel             int        NULL,
            mng_bank_id   int        NULL
        )
     
        insert into #tmp_af_adm_her
           select distinct ptcp.bank_id,ptcp.f_manager_id,convert( int, ptcp.tabel ),mng_bank_id
              from  dwh_stg..fr_ptcp_hist_adr ptcp
              where ptcp.bank_id = @bank_id
                and @last_dated between  ptcp.begin_date and isnull(ptcp.end_date,@last_dated)
  
        if ( @bank_id =  252  )
        begin
           insert into admin_hierarchy
                select distinct  252 ,                                                                   
                                bat.battalion_name,                                                    
                                bat.sadmin_name,                                                       
                                isnull( bat.admin_name, cdr.bidl ),                                
                                isnull( bat.departament_name, '' ),                                    
                                isnull( convert( int, cdr.emp_tablenum ), convert( int, ptcp.tabel )), 
                                isnull( cdr.emp_lastname, client.descr ) + ' ' + cdr.emp_firstname,    
                                isnull( cdr.emp_personcode, - 13  ),                                     
                                ptcp.mng_bank_id,
                                cdr.bidl,null                                                       
                    from #tmp_af_adm_her ptcp,
                         front_common..f_client client,
                         dwh_stg..cdr_employee cdr,
                         dwh_stg..cdr_bat_oe bat
                    where cdr.bidl *= bat.bid
                          and ptcp.f_manager_id = client.f_client
                          and convert( int, ptcp.tabel ) *= convert( int, cdr.emp_tablenum )
                          and datediff( mm, isnull( cdr.emp_dismissdate, @last_dated ), @last_dated ) <=  1 
                          and cdr.emp_oe1_id <>  2094 
Планы запроса строить для певого смысла нет, так как с индексами уже поигрался ))
Для вторго:

QUERY PLAN FOR STATEMENT 1 (at line 1).
STEP 1
The type of query is CREATE TABLE.
QUERY PLAN FOR STATEMENT 2 (at line 11).
STEP 1
The type of query is INSERT.
The update mode is direct.
Worktable1 created, in allpages locking mode, for DISTINCT.
FROM TABLE
dwh_stg..fr_ptcp_hist_adr
ptcp
Nested iteration.
Using Clustered Index.
Index : fr_ptcp_hist_adr_bank_idx
Forward scan.
Positioning by key.
Keys are:
bank_id ASC
Using I/O Size 4 Kbytes for data pages.
With MRU Buffer Replacement Strategy for data pages.
TO TABLE
Worktable1.
STEP 2
The type of query is INSERT.
The update mode is direct.
This step involves sorting.
FROM TABLE
Worktable1.
Using GETSORTED
Table Scan.
Forward scan.
Positioning at start of table.
Using I/O Size 4 Kbytes for data pages.
With MRU Buffer Replacement Strategy for data pages.
TO TABLE
#tmp_af_adm_her
Using I/O Size 4 Kbytes for data pages.
QUERY PLAN FOR STATEMENT 3 (at line 18).
STEP 1
The type of query is INSERT.
The update mode is direct.
Worktable2 created for REFORMATTING.
FROM TABLE
dwh_stg..cdr_bat_oe
bat
Nested iteration.
Table Scan.
Forward scan.
Positioning at start of table.
Using I/O Size 4 Kbytes for data pages.
With LRU Buffer Replacement Strategy for data pages.
TO TABLE
Worktable2.
STEP 2
The type of query is INSERT.
The update mode is direct.
Worktable1 created, in allpages locking mode, for DISTINCT.
FROM TABLE
#tmp_af_adm_her
ptcp
Nested iteration.
Table Scan.
Forward scan.
Positioning at start of table.
Using I/O Size 4 Kbytes for data pages.
With LRU Buffer Replacement Strategy for data pages.
FROM TABLE
front_common..f_client
client
Nested iteration.
Using Clustered Index.
Index : pk_f_client
Forward scan.
Positioning by key.
Keys are:
f_client ASC
Using I/O Size 4 Kbytes for index leaf pages.
With LRU Buffer Replacement Strategy for index leaf pages.
Using I/O Size 4 Kbytes for data pages.
With LRU Buffer Replacement Strategy for data pages.
FROM TABLE
dwh_stg..cdr_employee
cdr
Nested iteration.
Table Scan.
Forward scan.
Positioning at start of table.
Using I/O Size 4 Kbytes for data pages.
With LRU Buffer Replacement Strategy for data pages.
FROM TABLE
Worktable2.
Nested iteration.
Using Clustered Index.
Forward scan.
Positioning by key.
Using I/O Size 4 Kbytes for data pages.
With LRU Buffer Replacement Strategy for data pages.
TO TABLE
Worktable1.
STEP 3
The type of query is SELECT.
This step involves sorting.
FROM TABLE
Worktable1.
Using GETSORTED
Table Scan.
Forward scan.
Positioning at start of table.
Using I/O Size 4 Kbytes for data pages.
With MRU Buffer Replacement Strategy for data pages.

Просто смысл в том, что во временную таблицу попадает всего 1000 записей примерно из огромной таблицы fr_ptcp_hist_adr.Стало работать в 20 раз быстрее и я даволен )) Видимо просто изначально первый запрос был слишком кривой.
...
Рейтинг: 0 / 0
Как происходит умножение таблиц ???
    #34749967
--__Александр__--
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv
--__Александр__-- пишет:
> Практика показала, что произведение/сравнение по текстовому полю идет
> намного дольше, чем по числовому.

Ерунда полная.

> cdr.emp_tablenum являеться чаровскими, но в них храниться числовая
> айдишка (вот такой вот нонсенс). Поэтому и стоит конверт. Казалдось, что

Нет, будет медлееннее. Убирай.

> Второе, что я понял, лучше дистинкт убрать, а потом просто на
> задвоенность проверить. Но это гемор. Автоматизировать проверку
> задвоеености и удаление лишний строки - не так просто.

Да наверняка там не может быть в принципе дублирующих строк.
Просто надо знать свою БД

> Про битвин ясно. А вот дэйтдиф чем не понравился??? Его убрать нельзя ))
> Условие важное ))).

На between его что не заменить никак ?
Posted via ActualForum NNTP Server 1.4

Нефига не ерунда!!!!
select .....
from A1,A2
where A1.d1=A2.d2
Когда d1 и d2 - числовые - работает быстро. Когда d1 и d2 чаровские длинной 20 - работает дольше.
Первый вариант кода - писал не я, достался по наследству.
То что с конвертом медленне, уже понял -СПС.

Проверять данные на уникальность - времени нету. Поэтому задвоенности встречаються.
Ок, вывод ясен - функции в условиях лучше не указывать.
...
Рейтинг: 0 / 0
Как происходит умножение таблиц ???
    #34750150
москит
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
set statistics io on

        insert into #tmp_af_adm_her
           select distinct ptcp.bank_id,ptcp.f_manager_id,convert( int, ptcp.tabel ),mng_bank_id
              from  dwh_stg..fr_ptcp_hist_adr ptcp
              where ptcp.bank_id = @bank_id
                and @last_dated between  ptcp.begin_date and isnull(ptcp.end_date,@last_dated)

set statistics io off

Если есть индекс начинающийся с end_date или bank_id, end_date, то намного быстрее будет работать

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
set statistics io on

        insert into #tmp_af_adm_her
           select ptcp.bank_id,ptcp.f_manager_id,convert( int, ptcp.tabel ),mng_bank_id
              from  dwh_stg..fr_ptcp_hist_adr ptcp
              where ptcp.bank_id = @bank_id
                and ptcp.end_date >= @last_dated
                and ptcp.begin_date <= @last_dated
           union
           select ptcp.bank_id,ptcp.f_manager_id,convert( int, ptcp.tabel ),mng_bank_id
              from  dwh_stg..fr_ptcp_hist_adr ptcp
              where ptcp.bank_id = @bank_id
                and ptcp.end_date is null
                and ptcp.begin_date <= @last_dated

set statistics io off
...
Рейтинг: 0 / 0
Как происходит умножение таблиц ???
    #34750279
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
--__Александр__-- пишет:

> Нефига не ерунда!!!!
> select .....
> from A1,A2
> where A1.d1=A2.d2
> Когда d1 и d2 - числовые - работает быстро. Когда d1 и d2 чаровские
> длинной 20 - работает дольше.
> Первый вариант кода - писал не я, достался по наследству.
> То что с конвертом медленне, уже понял -СПС.

Как микросекунды вымерял ?
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Как происходит умножение таблиц ???
    #34750688
--__Александр__--
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
@begin_time = GETDATE()
@end_time = GETDATE()
DATEDIFF(ss,@begin_time,@end_time)+1)
На большой таблице не микросекунды разница)).
...
Рейтинг: 0 / 0
Как происходит умножение таблиц ???
    #34751893
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
--__Александр__-- пишет:
> @begin_time = GETDATE()
> @end_time = GETDATE()
> DATEDIFF(ss,@begin_time,@end_time)+1)
> На большой таблице не микросекунды разница)).

Ну и сколько же ?
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
23 сообщений из 23, страница 1 из 1
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Как происходит умножение таблиц ???
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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