|
План запроса в пакете и без
|
|||
---|---|---|---|
#18+
Adaptive Server Enterprise/12.5.4/EBF Вопрос больше теоретический. Есть некий пакет в котором во временную таблицу с индексами вставляются данные (около 90000 строк), затем идет серия апдейтов этих данных. insert #Temp... update #Temp... update #Temp... update #Temp... Так вот, обнаружилась интересная вещь: если выполнять каждый запрос последовательно, то оптимизатор корректно обнаруживает нужный индекс, все работает быстро. А если выполнить все в одном пакете, то на одном из запросов идет table scan. Если указать нужный индекс хинтом, то проблем не возникает. Почему так происходит? Ведь данные и в первом и во втором случае в таблице одни и те же. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15.
Код: plaintext 1. 2. 3. 4. 5. 6.
... |
|||
:
Нравится:
Не нравится:
|
|||
02.06.2011, 19:41 |
|
План запроса в пакете и без
|
|||
---|---|---|---|
#18+
План при выполнении всего пакета (без хинта с индеком). Код: 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.
План при выполнении только одного этого запроса (также без хинта с индеком). Код: 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. 44.
... |
|||
:
Нравится:
Не нравится:
|
|||
02.06.2011, 19:52 |
|
План запроса в пакете и без
|
|||
---|---|---|---|
#18+
On 02.06.2011 20:41, LelikB wrote: > Вопрос больше теоретический. Теоретически такого быть не должно. > Есть некий пакет в котором во временную таблицу с индексами вставляются данные > (около 90000 строк), затем идет серия апдейтов этих данных. > insert #Temp... После пачки insert-ов очень хорошо было бы сделать UPDATE STATISTICS. Или, ещё лучше, СНАЧАЛА вставлять данные, а ПОТОМ делать Код: plaintext 1. 2.
(UPDATE STATISTICS при этом уже не нужно ) Да, надеюсь, что create table и create index-ы у вас В ОТДЕЛЬНОМ БАТЧЕ ? > Так вот, обнаружилась интересная вещь: если выполнять каждый запрос > последовательно, то оптимизатор корректно обнаруживает нужный индекс, все > работает быстро. А если выполнить все в одном пакете, то на одном из запросов > идет table scan.Ведь данные и в первом и во втором случае в таблице одни > и те же. Да, и кстати, если вы не делаете так, как я выше написал, то оптимизатор при этом ничего о данных не знает. Код: plaintext 1. 2. 3. 4. 5. 6.
Странно, что не решают сканиться ВСЕ запросы на UPDATE, поскольку для оптимизатора таблица ваша пуста. Других данных у него нет, и он считает, что она пуста. Или немного заполнена. Скорее всего, случайно оптимизатор решает сканить именно на этом запросе. А ещё вернее всего, для остальных запросов table scan -- реально самая оптимальная стратегия, и вы просто не заметили, что там тоже table scan-ы. Posted via ActualForum NNTP Server 1.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
02.06.2011, 21:09 |
|
План запроса в пакете и без
|
|||
---|---|---|---|
#18+
On 02.06.2011 20:52, LelikB wrote: > И в первом и во втором случае данные в таблице одинаковые. Рассказывайте подробнее какими батчами всё это выполнялось в двух случаях, а особенно как create table и index. Да, кстати, "чисто теоретически" в таком случае вовсе не зазорно поставить хинты. Posted via ActualForum NNTP Server 1.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
02.06.2011, 21:12 |
|
План запроса в пакете и без
|
|||
---|---|---|---|
#18+
MasterZivДа, надеюсь, что create table и create index-ы у вас В ОТДЕЛЬНОМ БАТЧЕ ? Нет, все запросы в одном пакете. В общем-то в этом и была проблема, просто я не понимал почему для оптимизатора это может быть важно. MasterZivДа, и кстати, если вы не делаете так, как я выше написал, то оптимизатор при этом ничего о данных не знает. MasterZivдля оптимизатора таблица ваша пуста. Других данных у него нет, и он считает, что она пуста. Спасибо за развернутый ответ теперь все предельно понятно. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.06.2011, 13:39 |
|
План запроса в пакете и без
|
|||
---|---|---|---|
#18+
On 03.06.2011 14:39, LelikB wrote: > Да, надеюсь, что create table и create index-ы у вас В ОТДЕЛЬНОМ > БАТЧЕ ? > > > Нет, все запросы в одном пакете. И CREATE TABLE ? Posted via ActualForum NNTP Server 1.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
03.06.2011, 13:45 |
|
План запроса в пакете и без
|
|||
---|---|---|---|
#18+
MasterZiv, В данном конкретном случае create table и create index в одном пакете, а insert и серия update - в другом. Т.е. всего два пакета. Но я никогда не задумывался над необходимостью их разделения на разные пакеты, в данном случае я сделал это только для удобства. Не подскажете, почему это может быть необходимо? ... |
|||
:
Нравится:
Не нравится:
|
|||
03.06.2011, 14:39 |
|
План запроса в пакете и без
|
|||
---|---|---|---|
#18+
LelikBMasterZiv, В данном конкретном случае create table и create index в одном пакете, а insert и серия update - в другом. Т.е. всего два пакета. Но я никогда не задумывался над необходимостью их разделения на разные пакеты, в данном случае я сделал это только для удобства. Не подскажете, почему это может быть необходимо? Так как индекс создан до вставки, при вставке(insert), ASE нужно заполнить не только таблицу , но и индекс! плюс оптимизатор нечего не знает о статистике по этой таблице и по индексам. Нужно так: 1-батч: а. создал таблицу б. залил(insert) данные 2-батч а. сделал индекс б. сделал апдэйт И индекс создадите быстрей и статистика на апдэйтах будет актуальной!!! ... |
|||
:
Нравится:
Не нравится:
|
|||
03.06.2011, 14:54 |
|
План запроса в пакете и без
|
|||
---|---|---|---|
#18+
cherrex_Den Так как индекс создан до вставки, при вставке(insert), ASE нужно заполнить не только таблицу , но и индекс! А в случае кластерного индекса? Его-то наверняка имеет смысл создать до вставки? cherrex_Den2-батч а. сделал индекс б. сделал апдэйт Но тогда оптимизатор не будет знать об индексе при апдейтах, т.е. а. и б. также имеет смысл разделить? ... |
|||
:
Нравится:
Не нравится:
|
|||
03.06.2011, 15:35 |
|
План запроса в пакете и без
|
|||
---|---|---|---|
#18+
LelikB, LelikBА в случае кластерного индекса? Его-то наверняка имеет смысл создать до вставки? нет. оптимизатор строит план основываясь на статистику! он тупо может даже не знать сколько строк в таблице, если нет статистики по таблице. LelikBНо тогда оптимизатор не будет знать об индексе при апдейтах, т.е. а. и б. также имеет смысл разделить? Почему? Создания индекса еще как раз и обновляет статистику! ... |
|||
:
Нравится:
Не нравится:
|
|||
03.06.2011, 16:06 |
|
План запроса в пакете и без
|
|||
---|---|---|---|
#18+
LelikBMasterZivдля оптимизатора таблица ваша пуста. Других данных у него нет, и он считает, что она пуста. Спасибо за развернутый ответ теперь все предельно понятно. не считает он её пустой но и реальной картины у него нет насколько я помню из документации, оптимизатор предполагает некоторое кол-во записей ... в районе сотни, если не изменяет память ... |
|||
:
Нравится:
Не нравится:
|
|||
03.06.2011, 16:10 |
|
План запроса в пакете и без
|
|||
---|---|---|---|
#18+
On 03.06.2011 16:35, LelikB wrote: > А в случае кластерного индекса? Его-то наверняка имеет смысл создать до вставки? > cherrex_Den Нет. После. > Но тогда оптимизатор не будет знать об индексе при апдейтах, т.е. *а.* и *б.* > также имеет смысл разделить? Да. Я что понять-то не могу, так это как вы умудряетесь в один батч запихать create table, create index и всё остальное, когда вроде бы как все DDL дожны быть ТОЛЬКО ОТДЕЛЬНЫМ БАТЧЕМ (если не в процедуре или триггере). Posted via ActualForum NNTP Server 1.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
03.06.2011, 16:28 |
|
План запроса в пакете и без
|
|||
---|---|---|---|
#18+
On 03.06.2011 16:35, LelikB wrote: > А в случае кластерного индекса? Его-то наверняка имеет смысл создать до вставки? Вообще, не делали бы вы на временные таблицы-то кластерные индексы. Нафиг они там ? Posted via ActualForum NNTP Server 1.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
03.06.2011, 16:29 |
|
План запроса в пакете и без
|
|||
---|---|---|---|
#18+
On 03.06.2011 17:10, komrad wrote: > не считает он её пустой > но и реальной картины у него нет Ну я как бы загрубил, конечно, он ничего не считает, он просто использует статистику для таблицы по умолчанию, там (в разных версиях может быть по-разному) что-то типа 10 страниц, т.е. почти пустая таблица. Posted via ActualForum NNTP Server 1.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
03.06.2011, 16:31 |
|
План запроса в пакете и без
|
|||
---|---|---|---|
#18+
MasterZivOn 03.06.2011 17:10, komrad wrote: > не считает он её пустой > но и реальной картины у него нет Ну я как бы загрубил, конечно, он ничего не считает, он просто использует статистику для таблицы по умолчанию, там (в разных версиях может быть по-разному) что-то типа 10 страниц, т.е. почти пустая таблица. нашел таки в документации ;) цитатаThe optimizer assumes that any such table has 10 data pages and 100 rows. If the table is really large, this assumption can lead the optimizer to choose a suboptimal query plan. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.06.2011, 16:41 |
|
План запроса в пакете и без
|
|||
---|---|---|---|
#18+
MasterZiv Вообще, не делали бы вы на временные таблицы-то кластерные индексы. Нафиг они там ? Не задумывался над этим. Чтобы ссылка во втором ключе была сразу на CardID и в случае если надо узнать CardID по ResourceID, то не требовалось бы чтение таблицы, достаточно было чтения индекса. Можно, конечно, для достижения того же результата сделать CardID первичным ключом: Код: plaintext 1. 2. 3.
Код: plaintext 1. 2.
В чем будет недостаток временной таблицы в случае кластерного индекса? MasterZiv как вы умудряетесь в один батч запихать create table, create index и всё остальное, когда вроде бы как все DDL дожны быть ТОЛЬКО ОТДЕЛЬНЫМ БАТЧЕМ (если не в процедуре или триггере). Код: plaintext 1. 2. 3. 4. 5.
komrad , благодарю за ссылки. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.06.2011, 17:08 |
|
План запроса в пакете и без
|
|||
---|---|---|---|
#18+
[quot LelikB]MasterZiv Можно, конечно, для достижения того же результата сделать CardID первичным ключом: и сделать обычный индекс на CardID Написал не подумав, что для первичного ключа и так кластерный индекс будет создан. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.06.2011, 17:32 |
|
План запроса в пакете и без
|
|||
---|---|---|---|
#18+
On 03.06.2011 18:08, LelikB wrote: > Чтобы ссылка во втором ключе была сразу на CardID и в случае если надо узнать > CardID по ResourceID, то не требовалось бы чтение таблицы, достаточно было > чтения индекса. В этом что ли ? create clustered index i1 on #Card(CardID) create index i2 on #Card(ResourceID, CardRole) Это, извини, ты попутал. Это тебе не MSSQLServer, это ASE. В листах некластерных индексов ROWID лежит, а не значения ключей кластерного индекса. > Можно, конечно, для достижения того же результата сделать CardID первичным ключом: > > create table #Card > ( CardID numeric(*15*,*0*)primary key > .. > > и сделать обычный индекс на CardID и ResourceID: > > create index i1on #Card(CardID) Зачем тебе ДВА индекса по CardID ? > create index i2on #Card(ResourceID, CardRole) > > В моем случае происходит только одна вставка в таблицу, дополнительных данных в > середину таблицы (по CardID) не предвидится. > В чем будет недостаток временной таблицы в случае кластерного индекса? Да особенно ни в чём, просто на фиг он не нужен. Создание кластерного вызовет больше IO, потому что данные таблицы надо копировать, и ещё пересоздаст все некластерные индексы, если они есть. > Никаких проблем. Особенности связки Diasoft FA# --- BDE --- Sybase ASE? Не знаю ... странно очень. Posted via ActualForum NNTP Server 1.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
03.06.2011, 18:01 |
|
План запроса в пакете и без
|
|||
---|---|---|---|
#18+
MasterZiv, Код: plaintext 1. 2.
Спасибо за ответы! ... |
|||
:
Нравится:
Не нравится:
|
|||
03.06.2011, 18:37 |
|
|
start [/forum/topic.php?fid=55&msg=37293604&tid=2010316]: |
0ms |
get settings: |
8ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
44ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
50ms |
get tp. blocked users: |
1ms |
others: | 16ms |
total: | 151ms |
0 / 0 |