|
|
|
PLAN ORDER (навигация по индексу) и сохранение считанных recId в аналоге TreeSet
|
|||
|---|---|---|---|
|
#18+
"И снова здравствуйте!". При очередном перечитывании Писания : 1.2.3. Навигация по индексу Индексная навигация есть ни что иное, как последовательное сканирование ключей индекса. А так как для каждой записи серверу надо выполнить фетч записи и проверить ее видимость для нашей транзакции, то данная операция выходит достаточно дорогой. . . . Основное отличие индексной навигации от сканирования (описанного в пункте 1.2.2) заключается в отсутствии битовой карты между сканированием индекса и доступом к записи через ее идентификатор. Причина понятна - сортировка записей по физическим номерам в данном случае противопоказана. Из этого можно сделать вывод, что при индекс сканируется по мере фетча с клиента, а не "за раз" (как в случае использования битовой карты).- внезапно вспых вопрос. Почему нельзя сначала пройтись по всем ключикам (с учётом where / rows ограничений, если они есть) и затолкать ID'шники записей в структуру типа TreeSet, которую по окончании сканирования индеска можно спокойно юзать для обхода записей в порядке возрастания их ID - ? Да, понятно, что такой селект не выдаст клиенту ни одной строки до тех пор, пока не доберётся до последнего ключа и не начнёт выдавать содержимое TreeSet'a. Но селект ведь не только для выдачи результата клиенту юзается, а еще и просто для обработки строк в нужном порядке (т.е. курсором: for select ... from <T> where ... ORDER BY <F1, F2> as cursor C do ...) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.07.2014, 11:40 |
|
||
|
PLAN ORDER (навигация по индексу) и сохранение считанных recId в аналоге TreeSet
|
|||
|---|---|---|---|
|
#18+
ТаблоидПочему нельзя сначала пройтись по всем ключикам (с учётом where / rows ограничений, если они есть) и затолкать ID'шники записей в структуру типа TreeSet, которую по окончании сканирования индеска можно спокойно юзать для обхода записей в порядке возрастания их ID - ? лучше ответь зачем это нужно ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.07.2014, 12:05 |
|
||
|
PLAN ORDER (навигация по индексу) и сохранение считанных recId в аналоге TreeSet
|
|||
|---|---|---|---|
|
#18+
Что "зачем" ? Уменьшение числа random IO ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.07.2014, 12:52 |
|
||
|
PLAN ORDER (навигация по индексу) и сохранение считанных recId в аналоге TreeSet
|
|||
|---|---|---|---|
|
#18+
Таблоид, кхе... порядок IDшников записей далеко не всегда (читай почти никогда, если это не ПК) совпадает с порядком ключей сортировки ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.07.2014, 12:57 |
|
||
|
PLAN ORDER (навигация по индексу) и сохранение считанных recId в аналоге TreeSet
|
|||
|---|---|---|---|
|
#18+
Симонов Денис, даже ПК это не гарантирует. А кластерных индексов (Index Organized Table) в FB нету ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.07.2014, 12:59 |
|
||
|
PLAN ORDER (навигация по индексу) и сохранение считанных recId в аналоге TreeSet
|
|||
|---|---|---|---|
|
#18+
Симонов Денискхе... порядок IDшников записей далеко не всегда (читай почти никогда, если это не ПК) совпадает с порядком ключей сортировкиНу так я про то и говорю! Раз он не совпадает, значит, надо сначала пройтись по индексу и каждый ID записи, который там будет встречен, помещать предварительно в TreeSet. И только после окончания навигации начинать выталкивать из TreeSet'a его содержимое. Допустим, в индексе на страницах 123 и 124 сидят следующие ключи с ID'шниками: index page =>123123123123124124124124index keys =>abcabcdbcdebcdefbcdfabcdfbbczbcz2rec IDs =>65432112345678901265002112159014999991112 Навигация начинается с левого ключа, т.е. с 'abc'. Там ID'шник = 654321 - помещаем его в TreeSet, но НЕ выдаём ничего пока что клиенту. Далее переходим к ключу 'abcd', там ID'шник = 123456. Добавляем его в TreeSet, содержимое этого дерева будет теперь таким, что его итерация по его элементам выдаст (автоматом) их так: 123456, 654321. Затем переходим дальше, к ключу 'bcde', там ID = 789012, и т.д. В результате, по окончании этого процесса TreeSet будет таким, что итератор по нему выдаст элементы (ID'шники записей) в порядке их возрастания: TreeSet iter.next()21212345615901465002165432178901299999111 И вот только тут, на этапе итерации по этому дереву, начинаем проверять видимость записей нашей транзакции и выдаём их на гор а , если сиё допускается. И обходим эти записи уже в порядке возрастания ID'шников. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.07.2014, 13:17 |
|
||
|
PLAN ORDER (навигация по индексу) и сохранение считанных recId в аналоге TreeSet
|
|||
|---|---|---|---|
|
#18+
Таблоид, ну так порядок то будет не тот. Мы хотели вернуть записи в порядке ключей индексы, а после твоего алгоритма они нам вернутся в порядке расположения на диске. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.07.2014, 13:34 |
|
||
|
PLAN ORDER (навигация по индексу) и сохранение считанных recId в аналоге TreeSet
|
|||
|---|---|---|---|
|
#18+
ТаблоидИ обходим эти записи уже в порядке возрастания ID'шников И в какое место эти записи засунет пользователь, если он их просил совсем в другом порядке?.. То, о чём ты говоришь, это есть план INDEX. Который от ORDER несколько отличается. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.07.2014, 13:36 |
|
||
|
PLAN ORDER (навигация по индексу) и сохранение считанных recId в аналоге TreeSet
|
|||
|---|---|---|---|
|
#18+
Симонов Денисну так порядок то будет не тот. а, тьфу... точно :-) ну ладно, значит не судьба... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.07.2014, 13:36 |
|
||
|
PLAN ORDER (навигация по индексу) и сохранение считанных recId в аналоге TreeSet
|
|||
|---|---|---|---|
|
#18+
я в печальке большой: не могу в одном месте избавиться от этого PLAN ORDER'a, бызнес-логика его требует. И именно из-за него получаю совершенно дикие значения по произв-сти в трейсе. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.07.2014, 13:38 |
|
||
|
PLAN ORDER (навигация по индексу) и сохранение считанных recId в аналоге TreeSet
|
|||
|---|---|---|---|
|
#18+
ТаблоидИ именно из-за него получаю совершенно дикие значения по произв-сти в трейсе. Кэш увеличь, чтобы нужный индекс в него помещался. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.07.2014, 13:44 |
|
||
|
PLAN ORDER (навигация по индексу) и сохранение считанных recId в аналоге TreeSet
|
|||
|---|---|---|---|
|
#18+
Dimitry SibiryakovТаблоидИ именно из-за него получаю совершенно дикие значения по произв-сти в трейсе.Кэш увеличь, чтобы нужный индекс в него помещался. Кеш в SS поставил давно уже 512К, в трейсе при таком значении практически никогда не лезут read(s)>0. А в SC пробовал и с кешем 16384 (больше не задавал, вряд ли такое увидишь в реале :)), но read(s)>0 периодически прут. И сильно подозреваю, что даже если выставить в SC еще бОльший кеш ради истребления reads'ов - не поможет. Ибо SS тому пример. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.07.2014, 13:57 |
|
||
|
PLAN ORDER (навигация по индексу) и сохранение считанных recId в аналоге TreeSet
|
|||
|---|---|---|---|
|
#18+
Таблоидне могу в одном месте избавиться от этого PLAN ORDER'a, бызнес-логика его требует. бизнес логика не может требовать какого то плана. Сортировки может, но не плана. Если это связано с твоим тестом OLTP скажи в каком месте, может идеи какие придут. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.07.2014, 14:19 |
|
||
|
PLAN ORDER (навигация по индексу) и сохранение считанных recId в аналоге TreeSet
|
|||
|---|---|---|---|
|
#18+
Таблоидне могу в одном месте избавиться от этого PLAN ORDER'a насколько я в курсе, всегда можно избавиться от PLAN ORDER, только он поменяется на PLAN SORT. если при ORDER дофига random io, то SORT будет хорошо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.07.2014, 14:23 |
|
||
|
PLAN ORDER (навигация по индексу) и сохранение считанных recId в аналоге TreeSet
|
|||
|---|---|---|---|
|
#18+
Симонов Денис, там есть две процедурки, отвечающие за сторнирование количеств и стоимостей: sp_make_qty_storno & sp_make_cost_storno. У них (в твоей версии теста) курсоры, обрабатывающие строки, делают это с PLAN ORDER. Сколько я не крутил-мутил с индексами, ничего там не улучшилось. Курсорный запрос вида: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. - вгонял всё в гроб. После добавления волшебного "плюс-нолика" в его order by всё залетало, ускорение в десятки раз. Но это и другие исправления я еще тебе не высылал. Однако, остались еще режимы, где PLAN ORDER таки требуется. Это выбор случайных документов для обработки - то, что делает fn_get_random_id через вот то: select id from <view_for_random_search> where id >= :x ORDER BY ID rows 1. Почесав репу, я догадался, что вряде случаев можно и здесь убрать ORDER BY, потому что как только документ успешно залочен и взят в обработку, то при успешном её завершении он - возможно - исчезнет из видимости вьюхи <view_for_random_search>, т.к. перейдёт в такое состояние, когда по нему "всё сторнировано". Но это будет НЕ СРАЗУ, а при многократных обработках выбранного док-та, т.к. за один присест с него сдёргивается для сторнирования не всё кол-во. Поэтому мне совсем не нравится этот подход, ибо костыль же, явный и убогий. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.07.2014, 17:14 |
|
||
|
PLAN ORDER (навигация по индексу) и сохранение считанных recId в аналоге TreeSet
|
|||
|---|---|---|---|
|
#18+
kdvТаблоидне могу в одном месте избавиться от этого PLAN ORDER'aнасколько я в курсе, всегда можно избавиться от PLAN ORDER, только он поменяется на PLAN SORT. если при ORDER дофига random io, то SORT будет хорошо.Можно, ес-сно. Но только если объем записей для SORT'a не очень большой. Именно так у мну, к щясью, и происходит. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.07.2014, 17:15 |
|
||
|
PLAN ORDER (навигация по индексу) и сохранение считанных recId в аналоге TreeSet
|
|||
|---|---|---|---|
|
#18+
Таблоид, как раз когда есть ограничитель rows, да ещё и стоит там всего одна запись, PLAN ORDER будет эффективней чем SORT. Для трёшки вроде обещали сделать оптимизацию по-умолчанию для случая когда выбираются все записи. Сейчас это заметно когда есть JOIN. Оптимизатор меняет порядок соединения, если есть ограничитель ROWS. Код: sql 1. 2. 3. 4. 5. PLAN SORT (JOIN (COLOR NATURAL, HORSE INDEX (FK_HORSE_COLOR))) Код: sql 1. 2. 3. 4. 5. PLAN JOIN (HORSE ORDER HORSE_IDX_NAME, COLOR INDEX (PK_COLOR)) Правда сейчас абсолютно пофиг сколько я там укажу в rows хоть 10e9 план будет выбран второй. Может тебе сей пример чем и поможет ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.07.2014, 17:27 |
|
||
|
PLAN ORDER (навигация по индексу) и сохранение считанных recId в аналоге TreeSet
|
|||
|---|---|---|---|
|
#18+
Таблоидну ладно, значит не судьба...А нет, стоп. Всё таки - судьба! :-) Формируем битмап для хранения ID'шников, а также Tree Map , в котором: <Key> - это результат вычисления для каждой записи выражения ORDER BY (т.е. значений одного или нескольких полей); <Val> - это все прочие поля, не указанные в ORDER BY (кроме блобов, ес-сно; для них туда пишем только указатели). Стартуем так, как делается при PLAN INDEX, в итоге будет сформирован битмап. Далее, по нему делаем обход записей в порядке возрастания ID'шников, вытаскивая из записей все поля, которые были перечислены в ORDER BY и в SELECT-секции. Для каждой такой записи проверяем её видимость текущей транзакции и если Ок, то заполняем <key> & <val> нашего TreeMap'a. А затем - вываливаем вызывателю содержимое TreeMap'a, вызывая его итератор. В итоге получаем: 1) однократное посещение записей и только в порядке возрастания их ID; 2) вывод из TreeMap'a идёт в том порядке, что задан был в ORDER BY. Минус вижу только один: доп. расход памяти. Но в наш суровый век дешёвых терабайтов это не должно быть существенным. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.07.2014, 17:35 |
|
||
|
PLAN ORDER (навигация по индексу) и сохранение считанных recId в аналоге TreeSet
|
|||
|---|---|---|---|
|
#18+
Таблоид, и чем это лучше чем сортировка в памяти (не навигация по индексу) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.07.2014, 17:42 |
|
||
|
PLAN ORDER (навигация по индексу) и сохранение считанных recId в аналоге TreeSet
|
|||
|---|---|---|---|
|
#18+
Симонов Денискак раз когда есть ограничитель rows, да ещё и стоит там всего одна запись, PLAN ORDER будет эффективней чем SORT. Я не увидел этой эффективности, когда база под нагрузкой. Именно на запросах вида select ID from <view> where ID >= :x ORDER BY ID rows 1 неоднократно получал в трейсе то 5, а то 10 сек. И это при том, что ORDER BY - по первичному ключу, т.е. у нас достаточно большая вероятность того, что физ. порядок следования записей соотв-вует индексному. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.07.2014, 17:44 |
|
||
|
PLAN ORDER (навигация по индексу) и сохранение считанных recId в аналоге TreeSet
|
|||
|---|---|---|---|
|
#18+
Симонов Дениси чем это лучше чем сортировка в памяти (не навигация по индексу)Хм... не знаю, сравнивать надо. Но один плюсик всё же есть: не нужно будет костыли всовывать везде (я про "+0"). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.07.2014, 17:45 |
|
||
|
PLAN ORDER (навигация по индексу) и сохранение считанных recId в аналоге TreeSet
|
|||
|---|---|---|---|
|
#18+
Таблоид, значит у тебя вьюха хитрая. На простой таблице выигрыш просто огромный Код: sql 1. 2. 3. 4. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Код: sql 1. 2. 3. 4. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.07.2014, 17:55 |
|
||
|
PLAN ORDER (навигация по индексу) и сохранение считанных recId в аналоге TreeSet
|
|||
|---|---|---|---|
|
#18+
Симонов Денисзначит у тебя вьюха хитрая. Не, примитивизм сплошной: Код: sql 1. 2. 3. 4. 5. 6. Где fn_oper_retail_reserve() - детерминистик-функция, лезет в базу только при первом своём вызове. При последующих возвращает ID операции, сохранённый у себя в кошельке. И даже если заменить её на тупой литерал (у мну - 3000), не поможет, не в ней дело. Симонов ДенисНа простой таблице выигрыш просто огромныйКак-то не очень сильно бросилось в глаза... 16 мс против 63 ? это ты ведь в моно-коннекте сделал, так ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.07.2014, 18:39 |
|
||
|
PLAN ORDER (навигация по индексу) и сохранение считанных recId в аналоге TreeSet
|
|||
|---|---|---|---|
|
#18+
ТаблоидКак-то не очень сильно бросилось в глаза... 16 мс против 63 ? это ты ведь в моно-коннекте сделал, так ? это второй раз когда всё уже в кеш всосалось. Посмотри на количество фетчей. Когда указана инструкция rows 1, то огромного random IO быть не должно, так как после первого фетча всё прекратится. Разве что приходится целиком прочитать индекс и то в твоём случае должен быть Range Scan Код: sql 1. 2. 3. 4. тут скорее всего для optype_id есть дополнительный индекс вот тебе для сравнения Код: sql 1. 2. 3. 4. 5. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Чтений из кэша стало больше 34 vs 8 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.07.2014, 18:53 |
|
||
|
PLAN ORDER (навигация по индексу) и сохранение считанных recId в аналоге TreeSet
|
|||
|---|---|---|---|
|
#18+
Симонов Денистут скорее всего для optype_id есть дополнительный индекс есть, конечно же (см DDL, их есть у тебя). Только вот какое дело: не вижу я чё-то при работе в моноконнекте никаких осязаемых преимуществ order by id+0 над order by id. Вот пример. DDL: Код: 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. Test: Код: sql 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. Запусти у себя сначала с "declare c smallint = 1;", а затем поменяй на "declare c smallint = 2;", чтобы вызовы были с order by id+0. Я разницу как-то не ощутил. Может, в сильно-конкурентной среде, когда в таблицу `t` будут падать новые строки, будет всё по-другому, не знаю. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.07.2014, 20:32 |
|
||
|
|

start [/forum/topic.php?fid=40&msg=38706526&tid=1563438]: |
0ms |
get settings: |
6ms |
get forum list: |
13ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
178ms |
get topic data: |
6ms |
get forum data: |
2ms |
get page messages: |
38ms |
get tp. blocked users: |
1ms |
| others: | 200ms |
| total: | 448ms |

| 0 / 0 |
