Re: 100% загруженности SQL сервера 2000 | |
---|---|
PaulWist Автор Сообщений: 14621 Дата регистрации: 01.04.2004 |
Конечно , на T-SQL, поскольку SQLEXEC пересылает строку на выполнение (считай, что из QA выполняешь команду), другое дело, что можно использовать несколько подходов, что бы затолкать массив из 2000 элементов на сервер.
------------------ Есть многое на свете, друг Горацио... Что и не снилось нашим мудрецам. (В.Шекспир Гамлет) |
Re: 100% загруженности SQL сервера 2000 | |
---|---|
WiRuc Сообщений: 1012 Дата регистрации: 09.04.2002 |
Цитата: А что, RemoteView умеет вставлять кучу записей за раз? Только не надо про BatchUpdateCount, в любом случае будут оформляться отдельные Insert, только они будут объединены в один пакет. А его еще надо откомпилить, да и передать по сети. Вызов ХП на вставку для каждой записи через RPC будет выгодней, чем вставка через RemoteView. И не будем вспоминать про то, что ХП вообще то могут делать кучу работы внутри себя, не обмениваясь с клиентом промежуточными данными, что тоже сильно способствует ускорению работы. Ну, это основы построения клиент-сервера, думаю вы в курсе. Применение RemoteView оправдано на мой взгляд только в следующих случаях: 1) Крупное многоплатформенное приложение, когда поддерживать нескольких версий серверной части становиться невыгодно. 2) Желание быстро портировать Фоксовое приложение на клиент-серверную основу. 3) В случае осуществления выборок со сложной динамической фильтрацией. На основе ХП это реализуется довольно тяжко, а вот на клиенте построить динамический селект проще простого. Так что, все изменения БД должны вестись через ХП (тут возможен вариант с CursorAdapter и "ручным" оформлением команд на изменение БД с помощью ХП, хотя я использую класс на основе SQLEXEC), да и большая часть выборок тоже. Все вышесказанное, естественно, IMHO. |
Re: 100% загруженности SQL сервера 2000 | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Hi, WiRuc!
Ну а как насчёт управления транзакциями? "Внешнее" управление позволит сделать все изменения за 1 (ну пускай даже 1 на скажем 1000 INSERT-ов) транзакцию, не потеряем ли мы этой возможности используя ХП? А вообще все массовые операции практически на всех СУБД выполняются вовсе не через SQL, а специализированными утилитами - bulk copy и т.п. Ибо скорости там порой на несколько порядков большие... И кстати чем тебя не устраивает SQLPREPARE() - AFAIK тогда тоже собственно команда передаётся по сети и компилируется 1 раз, потом лишь параметры качаются (т.е. реальные данные) и на сервере уже откомпилированная команда исполняется. Насчёт недостатков (ну точнее я например не знаю как это можно по нормальному решить ни на MS SQL, ни на Oracle): Предположим что у нас есть таблица - TestTable (n1 Int, c1 varchar(10), d1 DateTime) На неё навешены Default-ы или триггера на вставку (в Oracle скажем автонумерация из Sequence в триггере и подключается). И мы хотим вставить в эту табличку НЕПОЛНЫЕ данные - например у 10 записей нету n1 (надо чтоб сработал Default или триггер), ещё у 10 нету c1 у каких-то нету И с1 И n1 ну и т.д. Если это делать со стороны фокса, то анализируя поля на EMPTY() можно в одном случае сформировать команду INSERT INTO TestTable (n1, c1, d1) VALUES (...) в другом INSERT INTO TestTable (c1, d1) VALUES (...) А в третьем и вовсе INSERT INTO TestTable (d1) VALUES (...) И всё будет работать! А вот как такого добиться используя ХП? передавать NULL? Но тогда NULL и вставиться (если позволит поле), и Default не сработает, и триггер (вполне справедливо) посчитает что значение поля таки БЫЛО явно задано... Анализировать в ХП все параметры и по этому анализу "внутри" формировать один из вышеуказанных вариантов? Но тогда представим таблицу с 50-ю полями и "окинем взглядом" получившийся код Учитывая что при Update возникают примерно такие-же проблемы, становится совсем печально Подскажи, как же ты выходишь из подобных ситуаций? ------------------ WBR, Igor |
Re: 100% загруженности SQL сервера 2000 | |
---|---|
WiRuc Сообщений: 1012 Дата регистрации: 09.04.2002 |
Цитата: Ну, вообще-то я считаю, что управлением транзакциями должна заниматься серверная часть. Т.е. клиент стартует ХП, она открывает транзакцию, делает какие-то действия и закрывает или откатывает транзакцию. В MSSQL управление транзакциями с клиента вообще подобно самоубийству, например, открыли документ на редактирование - открыли транзакцию минут эдак на 10 и пошли блокировки на все и вся. У Oracle, т.к. он версионник, с этим попроще, там можно такое практиковать, хотя это тоже не совсем хорошо. Кроме того, такой подход позволяет, например при возникновении деадлока или обрыве соединения с сервером, просто перезапустить ХП, не прерывая работу программы. Конечно, бывают моменты, когда необходимо запускать транзакцию с клиента, но кол-во таких случаев необходимо минимизировать. Цитата: Естественно. И уж не через RemoteView однозначно... Цитата: Я уже приводил здесь результаты работы SQLPREPARE для MSSQL. После того, как я обнаружил эту "особенность", желание использовать SQLPREPARE у меня пропало. Помимо этого, при использовании в качестве параметров сивольных строк происходит "засорение" кэша сервера. Например, мы вызываем команду INSERT INTO table (name) VALUES (?m.cName), где cName - это символьная переменная. В этом случае, для каждого размера переменной (длины строки) будет создан и сохранен в кэше собственный план. Т.е. для cName='a' - это один план, для cName='ab' - еще один план и т.д. для всех вариантов длины строки в переменной. Это на MSSQL, не знаю, как обстоит с этим дело у Oracle. И, напоследок, даже при вызовы через SQLPREPARE накладные раходы чуть выше, чем непосредственный RPC вызов ХП. Цитата:О, это моя любимая тема Один из самых значительных недостатков при использовании ХП. Для вставки в принципе все довольно просто. Тут есть два варианта: 1) Т.к. ВСЕ изменения в БД делаются через ХП (в том числе и в высокоуровневых ХП), то DEFAULT вешаются не на таблицу, а на параметры ХП. В результате вызов ХП оформляется как UP_BASE_INSERT ?id,DEFAULT,?m.cName 2) В ХП на вставку фактически производится две операции: вставка и обновление. Т.е. сперва мы осущемствляем вставку с МИНИМАЛЬНО необходимым набором полей. После этого производится обновление записи для остальных полей. insert into table (id) values (@id) update table set name=isnull(@name,name) Этот вариант помедленней первого, да и вообще похуже. Например, не допускает появления NULL в полях, а, если допускается, то тогда необходимо передавать маску обновлений в ХП. Для UPDATE все гораздо хуже, хотя тут тоже возможны 3 варианта. 1) Не используем NULL в полях таблицы. В этом случае можно передавать в качестве параметра NULL для тех значений, которые не требуется обновлять. update table set id=isnull(@id,id), name=isnull(@name,name) 2) Используем маску обновлений. Смысл в том, чтобы строить на клиенте битовую маску, в которой для тех значений, которые необходимо обновлять, ставим 1. И в ХП, помимо самих значений полей, передаем еще и эту маску. update table set id=(CASE WHEN GetUpdateBit(@updmask,1)=1 THEN @id ELSE id END), name=(CASE WHEN GetUpdateBit(@updmask,2)=1 THEN @name ELSE name END) Ну, и конечно, есть третий вариант - использовать узкоспециализированные ХП, обновляющие 1-N... полей. Например, ХП обновляющая только цену и кол-во в строке спецификации документа. Конечно, ни один из вариантов не идеален С другой стороны, если бы в жизни было все просто, тогда было бы совсем скучно |
Re: 100% загруженности SQL сервера 2000 | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Hi, WiRuc!
Цитата:Я тоже так считаю, однако вот такой вот "массированный импорт" это как раз исключение из правила - ну или нужно найти способ в ХП передать сразу большой массив записей (не уверен, но наверное XML тут как раз подойдёт - но вот сама ХП тогда может стать слишком уж сложной ) И конечно транзакция не должна "висеть"! Цитата:Я в курсе про этот баг, пока сам не использую активно, но что-то мне подсказывает что долен быть способ обойти такое наглое поведение ODBC... Ибо по всем правилам прекомпиляция должна ускорить работу Цитата:Не понимаю, там же вроде одинаковый объём инфы передаётся - те-же параметры практически всё и съедают... Цитата:;) Цитата:Угу. Цитата:Хм, надо посмотреть как с этим у Oracle дела обстоят... Что-то меня терзают смутные сомнения, что не очень хорошо там будет с этим вариантом Цитата:Да, именно про то я и говорю - NULL тут уже не NULL, а признак "использования Default-а". Да и как тогда решить проблему с триггерами и т.п. пакостями Ведь сработает эта зараза даже если Default на Default менять А писать кучу "маленьких" UPDATE-ов (по одному полю за раз) внутри соответствующих IF-ов совсем некрасиво получается Цитата:Вот вот - куча лишних телодвижений получается Цитата:Ты рассмотрел пока лишь трудности программирования собственно ХП - а ведь всё это ещё как-то надо привязать к фоксу! И если Update и Insert он автоматом строит вполне корректный, то отказ от прямых команд повлечёт необходимость написания неслабого кода в BeforeUpdate/BeforeInsert для CursorAdapter - ну или аналогичного кода при "ручном" управлении курсором (не через CA). Конечно если не считать за разумный выход прописывание УНИКАЛЬНОГО, т.е. неуниверсального кода в каждый такой управляющий объект, или CA. Цитата:Но и искать себе лишние сложности тоже не стоит ------------------ WBR, Igor |
Re: 100% загруженности SQL сервера 2000 | |
---|---|
Владимир Максимов Сообщений: 14100 Откуда: Москва Дата регистрации: 02.09.2000 |
Ребята, пока вы не слишком углубились в дискуссию о проблемах массовой вставки записей (читай сотни и тысячи) и как это можно ускорить. Такой вопрос:
Насколько часто встречается необходимость в таких массовых вставках? Есть ли смысл "копья ломать", если процесс относительно редок? Может пользователь согласен "потерпеть" или это можно решить организационно (например, перенести этот процесс на ночь или на выходные)? Не знаю, как вы, но прежде чем отвечать на вопрос "Как?", я пытаюсь ответить на вопрос "А оно действительно нужно?" ------------------ |
Re: 100% загруженности SQL сервера 2000 | |
---|---|
PaulWist Автор Сообщений: 14621 Дата регистрации: 01.04.2004 |
2WiRuc
Прошу пояснить Цитата: Если несколько ХП используют конкретную таблицу и нам необходимо использовать логику модификации, то возникает необходимость Default-ы прописывать в нескольких местах (ХП), вместо одного - у таблицы, на мой взгляд такой подход не совсем правильный. Цитата: Теоретически , поддерживаю такой подход, но практически не всегда можно этого добиться Цитата: Вообщем-то выход. А почему не использовать sp_executesql и динамически строить запрос на самом сервере. Цитата: И здесь прошу пояснения, почему на сервере построить дин. запрос сложнее чем на клиенте , если известны условия выборки. ------------------ Есть многое на свете, друг Горацио... Что и не снилось нашим мудрецам. (В.Шекспир Гамлет) |
© 2000-2024 Fox Club  |