|
|
|
Проблема с Plan когда во Where есть in(,,,,)
|
|||
|---|---|---|---|
|
#18+
Из-за неэффективности планировщика запросов Interbase (медленнее в 30 раз, чем в явно заданном мною плане для некоторого множества типовых запросов к таблицам бухгалтерии) есть потребность в такой схеме действий: 1. Спросить у Interbase план запроса 2. Поменять его по выявленному нами алгоритму: а) поменять порядок параметров в директиве join(таблица1(индексы),таблица2(индексы),...)), т.е. установить оптимальный порядок сканирования таблиц б) убрать использование лишних индексов для одной из таблиц (там по смыслу всегда нужен единственный индекс) 3. Послать в Interbase запрос с явно заданным планом Но возникает очень серьезная проблема, когда во WHERE для ключевых полей есть ограничение по IN, например, WHERE (Date>'01.01.2003') AND (AccID in (111,222,333)). В этом случае Interbase в плане запроса указывает использовать индекс по AccID несколько раз: PLAN SORT(JOIN(Entry(Entry_Date, Entry_AccID, Entry_AccID, Entry_AccID))). Однако, попытка использовать этот план явно терпит фиаско :((( Interbase выдает сообщение, что индекс Entry_AccID не м.б. использован в этом случае. Возникает предположение, что индексные поля, ограниченные IN(....) действительно не м.б. использованы в плане. Но это неверно! Указываю явный план SORT(JOIN(Entry(Entry_Date))) и выборка идет медленнее в 2 раза, чем если план не указывать (т.е. используется план по умолчанию, упоминавшийся выше). ТАКИМ ОБРАЗОМ: Проблема: для in(,,,) IB показывает план запроса в синтаксисе непригодном для явного использования. Вопрос: кто подскажет верный синтаксис? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.08.2003, 14:36 |
|
||
|
Проблема с Plan когда во Where есть in(,,,,)
|
|||
|---|---|---|---|
|
#18+
Давай по-порядку... Приводи текст запроса, приводи план(ы) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.08.2003, 15:02 |
|
||
|
Проблема с Plan когда во Where есть in(,,,,)
|
|||
|---|---|---|---|
|
#18+
Итак, по порядку: 1. Запрос: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 2. План, используемый Interbase по информации IB Console Код: plaintext 1. 2. 3. 3. Статистика: Execution time 9 s Prepare Time 0 Starting Memory 17800192 Current Memory 21239808 DeltaMemory 3439616 Number of Buffers 2048 Reads 357 Writes 5 4. Запрос с явным планом, который я указываю: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 5. Статистика с моим планом: Execution time 1.06 s Prepare Time 0 Starting Memory 17806336 Current Memory 17961984 DeltaMemory 155648 Number of Buffers 2048 Reads 1713 Writes 11 6. Проблема: Хочу план по алиасу CC таким и оставить: Код: plaintext т.к. здесь нужен единственный индекс, а вот для алиаса A я хотел бы использовать индекс ENTRYCORR_12000101ACCID по полю ACCID, но Interbase ругается. Более того, если я просту явно укажу первый вариант плана, который сам же Interbase мне и предоставил, то ошибка та же: Index ENTRYCORR_12000101ACCID cannot be used in the specified plan. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.08.2003, 15:41 |
|
||
|
Проблема с Plan когда во Where есть in(,,,,)
|
|||
|---|---|---|---|
|
#18+
... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.08.2003, 16:37 |
|
||
|
Проблема с Plan когда во Where есть in(,,,,)
|
|||
|---|---|---|---|
|
#18+
http://www.krista.ru/ib/ ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.08.2003, 16:38 |
|
||
|
Проблема с Plan когда во Where есть in(,,,,)
|
|||
|---|---|---|---|
|
#18+
А запрос ты формируешь динамически на клиенте , я имеюю в виду: Код: plaintext 1. 2. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.08.2003, 16:55 |
|
||
|
Проблема с Plan когда во Where есть in(,,,,)
|
|||
|---|---|---|---|
|
#18+
Да и еще http://ibase.ru/devinfo/dontdoit.htm][пункт №15] ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.08.2003, 16:58 |
|
||
|
Проблема с Plan когда во Where есть in(,,,,)
|
|||
|---|---|---|---|
|
#18+
> VOVA: А запрос ты формируешь динамически на клиенте , я имеюю в виду: Да, на стороне клиента есть библиотека, которая по некоторому стандартизированному запросу к бухитогам в объектной нотации выдает SQL ваиант на сервер, получает результат и позволяет опять таки в объектной нотации разобрать этот результат. > VOVA: Да и еще [пункт №15] Спасибо за совет, подумаем. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.08.2003, 17:30 |
|
||
|
Проблема с Plan когда во Where есть in(,,,,)
|
|||
|---|---|---|---|
|
#18+
1. Попробовать перегенерировать селективность индексов (SET STATISTICS) 2. Наверно надо избавиться от HAVING (перенести условия NOT NULL в WHERE) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.08.2003, 07:55 |
|
||
|
Проблема с Plan когда во Where есть in(,,,,)
|
|||
|---|---|---|---|
|
#18+
> Voha Мои глубочайшие извинения за ошибку в указании Вашего имени. > Alexandr K. Благодарю за помощь, я так и попробовал, но результат тот же "Index ENTRYCORR_12000101ACCID cannot be used in the specified plan". После многодневных экспериментов я убедился, что причина единственная - ошибка в Interbase, касающаяся синтаксиса планов, когда есть where...in... Для обоснования упрощаю исходный запрос до предела (вопросы производительности join уже подняты и обоснованы, теперь сконцентрируемся только на проблемах синтаксиса). Итак, для запроса: Код: plaintext 1. 2. 3. 4. 5. Interbase по данным IB Console использует план: Код: plaintext 1. Пробую его "тупо" подставить (не забывая о переделке статистики индексов): Код: plaintext 1. 2. 3. 4. 5. 6. Получаю диалоговое окно с ошибкой: Код: plaintext 1. 2. 3. Теперь убираю IN и проверяю бухсчет на равенство: Код: plaintext 1. 2. 3. 4. 5. 6. Все прекрасно работает. Таким образом ясно одно: для IN - Interbase использует индексы, но отображает план для этого случая некорректно, или отображает корректно, но некорректно на него реагирует при явном указании в SELECT. А какой синтаксис корректный - не ясно. P.S. Если не использовать Код: plaintext 1. 2. то результат тот же. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.08.2003, 09:54 |
|
||
|
Проблема с Plan когда во Where есть in(,,,,)
|
|||
|---|---|---|---|
|
#18+
Я может не совсем вдуплил, но может стоит использовать временную таблу и на основе ее производить проверку? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.08.2003, 10:20 |
|
||
|
Проблема с Plan когда во Where есть in(,,,,)
|
|||
|---|---|---|---|
|
#18+
> Voha: ... использовать временную таблу ... Попробовал. И вышло следующее. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. Сработало! Хотя Interbase и показал для данного указанного плана его фактический план: Код: plaintext 1. Опаньки!!! Нашел причину. Причина должны была быть в отличии а отличие в том, что я "пожадничал" и не создал поле ID оно же Primary Key. Итак, удаляю таблицу и ключ и делаю все заново, но с ID. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. Не работает! Вылетает старая добрая ошибка, что sotrudnik_otdel использовать в плане нельзя. Тогда пробую ради прикола применить это ограничение к полю с первичным ключом: Код: plaintext 1. 2. Работает! Можете проверить. Вывод: Interbase использует индекс, но не дает явно указывать его в плане запроса, если этот индекс не Primary Key или если по другому полю есть Primary Key. Железная логика у интербейза . Еще один повод задуматься о всеобщем детерминизме и фатализме :). Что же делать?.... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.08.2003, 14:39 |
|
||
|
Проблема с Plan когда во Where есть in(,,,,)
|
|||
|---|---|---|---|
|
#18+
Попробуй FIB там много вещей исправлено, которые в интербасе работали некорректно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.08.2003, 14:55 |
|
||
|
|

start [/forum/topic.php?fid=40&fpage=506&tid=1580039]: |
0ms |
get settings: |
7ms |
get forum list: |
17ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
61ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
46ms |
get tp. blocked users: |
2ms |
| others: | 222ms |
| total: | 377ms |

| 0 / 0 |
