MS SQL Server 2000 проблема с запросом

Тема в разделе "SQL", создана пользователем Barmutik, 18 ноя 2004.

Статус темы:
Закрыта.
  1. Barmutik

    Barmutik Гость

    Появилась следющего рода проблема:

    Есть таблица с некоторым набором полей. В таблице есть IDxx (типа int)- Primary key. Встала необходимость делать запросы следующего вида:
    SELECT IDxx, MyField FROM MyTAble WHERE IDxx IN (.....)

    Проблема заключается во времени реации сервера на запрос.

    Если количество значений в IN не большое то запрос работает мгновенно... Но если она ставновится больше 500 ... то время реакции увеличивается до 8-10 секунд.... что не приемлимо...

    Проблема абсолютно непонятна учитывая что в данной таблице порядка 4000 (4 тысячи всего) записей...

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

    Повторный запрос происходит мгновенно .. что в принципе и понятно он находится в кэше сервера.

    Серверный компьютер: 2-х процессорный на Intel Pentium 4 2.8 Gh c 2 Gb оперативки

    Подскажите в чём грабли ... :)
     
  2. Barmutik

    Barmutik Гость

    Забыл указать: проблема в MS SQL Server 2000 Enterprise Edition
     
  3. Pete

    Pete Гость

    Действительно странно

    а если тоже самое расписать через IDxx = V1 OR IDxx = V2 ...?

    или попробовать предварительно отсортировать значения в IN ? Может сервак как-нибудь отслеживает такую возможность оптимизации запроса? Хотя по идее микрософтовцы должны были догадаться использовать хэш или сортировку значений...

    Короче ХЗ, никогда не сталкивался с такой ерундой...
     
  4. ????

    ???? Гость

    Barmutik
    А план выполнения запроса? Может там что (наприемр не используется индекс)? В IN(...) подзапрос или числа (подозреваю что подзапрос :) )? Попробуй переписать используя minus (если это конечно возможно) или NOT EXISTS.
    Может с этой таблицой связанно 300 дркгих по FK и происходит каскадное удаление :) ?
     
  5. Pete

    Pete Гость

    Да EXPLAIN мог бы помочь, вдруг при большом количестве IN (...) вместо индекс используется полный последовательный проход по таблице, а, вообще гадать можно долго... Только уж точно не каскадное удаление там виновато =))
     
  6. Barmutik

    Barmutik Гость

    Подробнее...

    План запроса выглядит следующим образом:

    SELECT (0%) <- Primary KeyIndex Selection (100%)

    Посмотрел что приходит конкретно на выполнение серверу после препроцесора и оптимизатора запросов:

    ID = x OR ID = y OR ID = z OR... и так далее

    Все значения отсортированы .. я пробовал сам сортировать но потом увидел что оптимизатор их сортирует даже если я их даю не сортированные.

    Значения в IN это список константных значений типа int ... не подзапрос!

    Этот список я получаю от сторонней программы которая его готовит по своим правилам. Далее по этому списку значений я должен отобразить список записей с указанными ID.

    Абсолютно не понятно где берутся такие тормоза ;) Всё что я знал об оптимизации и настройках SQL Server я уже попробовал.. остаются только советы...

    По поступившим из других источников советам: люди советуют создавать временную таблицу в неё вставлять записи а потом делать JOIN. Говорят что будет значительно быстрее.. особенно чем больше количество элементов в IN тем больше будет разница.. надо будет попробовать.. но какой-то кривой подход. Ещё сказали что это проблема SQL Server .. что он так криво отрабатывает IN

    Вот и думай тут что хочеш.... и это при 4000 в таблице .. а что ж будет когда будет 400.000 ;)
     
  7. ????

    ???? Гость

    Barmutik
    А что если попробовать создать ХП с данным селектом? Может на разбор данной конструкции уходит очень большое время? А ХП находится в откомпилированном состоянии, запрос разобран и получим только время исполнения.
    В Oracle есть 2 вида разбора запроса - hard parse и soft parse. При запросе select * from dual where X = 1 - hard parse, т.е. каждый раз запрос будет парсится полностью, а если select * from dual where X = :bind_var - soft parse. Может в MSSQL есть что-то подобное?
     
  8. Barmutik

    Barmutik Гость

    Хммм... интересная мысль....

    Просто проблема в том .. что запрос строится на лету и этот IN лиш одна малая составляющая часть этого запроса...

    Разбор кем ? Оптимизатор проускает через себя за 0.01 секунды .. приблизтельно ...
     
  9. Pete

    Pete Гость

    2????: А как в ХП передать переменное кол-во аргументов? Мне бы тоже пригодилось =) Я пока такого не встречал, к сожалению.

    Может попробовать разбить один бальшой запрос на несколько маленьких, а потом сгруппировать результаты? Криво согласен, но если не найдется другого варианта, то это можно попробовать, тем более, что скорость работы запроса зависит нелинейно от кол-ва значений в IN.

    Насчет JOIN тоже не факт что поможет, запросы с JOIN как правило работают не очень быстро, особенно когда несколько таблиц объединяются.

    >План запроса выглядит следующим образом:
    >SELECT (0%) <- Primary KeyIndex Selection (100%)

    Я не совсем в курсе, но может возможно запретить использовать индекс для кокретного запроса??? Я бы еще попробовал использовать проход по таблице, индекс ведь не всегда быстрее оказывается. Еще вариант, если у тебя в IN больше половины всех возможных значений, которые в нем могут быть, может имеет смысл построить запрос тогда через NOT IN, сделав соотв. проверку? (правда для этого надо знать какие значения не входят в исходное множество, что тоже может быть проблематично)

    >По поступившим из других источников советам: люди советуют создавать временную таблицу в неё вставлять >записи а потом делать JOIN. Говорят что будет значительно быстрее.. особенно чем больше количество >элементов в IN тем больше будет разница.. надо будет попробовать.. но какой-то кривой подход. Ещё >сказали что это проблема SQL Server .. что он так криво отрабатывает IN

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

    ???? Гость

    Pete
    тынц
    можно использовать ХИНТЫ (Hint), правда для MS SQL не знаю как (в Oracle select /*+ имя_хинта(параметры)*/ ...)
     
  11. Barmutik

    Barmutik Гость

    Не помогает отключение индекса.... ;)
     
  12. Barmutik

    Barmutik Гость

    Вообщем ситуация следующая:

    Если элементов в IN от 40-65% от объёма таблицы ситуация наиболее печальная ...

    Вышел из ситуации следующим образом:

    1. Создание временной таблицы (0.001 с)
    2. Загрузка в неё списка ИД (0 -... с)
    3. Обычный JOIN с моей таблицей (0.2- 0.4с)

    Наиболее затратный по времени сейчас пункт 2. И чем больше элементов тем вроде как затратнее. Но тут хорошо подошло решение с BULK INSERT... время на вставку 3000 в пределах десятых секунды...

    В принципе если количество в IN перевалит за 20.000 то можно попытаться выйти на самый низкий уровень и попытаться использовать IFastRecordLoad интерфейс .. на точное название не претендую ... но в моей ситуации пока это не требуется.

    Вообщем время выполнение сейчас находится в пределах 1 секунды .. что пока приемлимо...

    Так что ничего более умного и быстрого пока изобрести не смог.... :)

    Но в очередной раз поразился качеству написания программ от фирмы Microsoft... программа стоимость которой переваливает за 20.000 иностранных(что бы не было пертензий... SQL Server ЛЕГАЛЬНО КУПЛЕН!!!) позволяет себе так тупить на банальных задачах.... ;)
     
  13. Pete

    Pete Гость

    2????: спасибо за ссылку, интересно было посмотреть как люди извращаются, но как я понял все это адаптировано к MS SQL, но ведь не все им пользуются. Но конечно прикольно =)
     
  14. Pete

    Pete Гость

    Тут знакомый подсказал альтернативное решение, может подойдет: переменные в IN получаются по определенному критерию, может можно "выдрать" из thirdparty проги сам критерий отбора, и применить его, вместо передачи результата отбора??? Или не катит?
     
  15. Pete

    Pete Гость

  16. ????

    ???? Гость

    Barmutik
    По пункту 2:
    для быстрой вставки отключи все констрэйнты, триггеры и индексы :)
    Pete
    еще нет, а 10g уже работает полным ходом. Yukon будет работать на 1-2 ОС, 1-2 архитектурах, а 10-ка работает на всех известных мне ОС (серверных) и почти на всех процах. Orale - это не СУБД, это МЕГА suit различных технологий, которых полностью достаточно для реализации сколь угодно сложных систем.
    З.Ы. Чуть не забыл - Oracle самоя документированная СУБД, а может и система в мире. У "меня" как минимум 10000 страниц документации на русском, причём 80% официальной.
     
  17. Barmutik

    Barmutik Гость

    Кого отключать :) Временная таблица из одного поля ;)
     
  18. ????

    ???? Гость

    Barmutik
    Тошно, не подумал :)
    тут уж пользователь пусть ждёт. Стандартно принято до 1000(0) записей за секунду.
     
  19. Barmutik

    Barmutik Гость

    Да нет тот IFast... позволяет (по описаниюв хелпе) вставлять около 500.000 в секунду... но я как посмотрел .. там надо столько самому делать .. что стало просто лениво :) Пока лениво .. а если припрёт то буду разбираться ...
     
  20. Igori

    Igori Гость

    Скажите пожайлуста где можно скачать нормальную версию SQL Server 2000 У меня ключ есть а вот программу не знаю откуда скачать Только не Evalution Version
     
Загрузка...
Статус темы:
Закрыта.

Поделиться этой страницей