• 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

    На последнюю неделю приходится экзамен, где нужно будет показать свои навыки, взломав ряд уязвимых учебных сайтов, и добыть флаги. Успешно сдавшие экзамен получат сертификат.

    Запись на курс до 25 апреля. Получить промодоступ ...

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

  • Автор темы Barmutik
  • Дата начала
Статус
Закрыто для дальнейших ответов.
B

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 оперативки

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

Barmutik

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

Pete

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

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

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

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

????

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

Pete

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

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 ;)
 
?

????

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 есть что-то подобное?
 
B

Barmutik

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

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

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

Pete

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

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

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

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

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

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

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

????

Pete
А как в ХП передать переменное кол-во аргументов?

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

Barmutik

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

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 ЛЕГАЛЬНО КУПЛЕН!!!) позволяет себе так тупить на банальных задачах.... ;)
 
P

Pete

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

Pete

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

Pete


Comparing Oracle 10g and SQL Server Yukon

Правда автор замечен в симпатиях к мелкомягким.
 
?

????

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

Barmutik

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

Barmutik

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

Igori

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

Обучение наступательной кибербезопасности в игровой форме. Начать игру!