Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Informix [игнор отключен] [закрыт для гостей] / Два вопроса по оптимизации / 10 сообщений из 10, страница 1 из 1
30.05.2005, 15:01
    #33090826
falcon111
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Два вопроса по оптимизации
1. Если сервер стоит на XP на процессоре p4 с гипертредингом (northwood 3.2).
Что указывать в MULTIPROCESSOR, NUMCPUVPS и SINGLE_CPU_VP ?
С одной стороны - процессор все же один. С другой - вроде как и не один...

2. Есть вьюшка, одно из ее назначений - показывать только часть записей из таблицы - те, которые клиент имеет право видеть. Чтобы получить id и прочие атрибуты клиента я сделал несколько процедур, типа getmyuid() getmycategory() getmystatus() и т.д. - все, что они делают - выбирают какое-либо поле из таблицы клиентов глядя на user сессии.
Посмотрел я на explain оптимизатора, который он выдает при выборке по подобной вьюшке - и ничего не понял. Я надеялся, что оптимизатор заставит сперва один раз отработать мои процедуры, и с их результатами сравнивать выбираемые строки пользуясь индексами, а получается, по-моему, что мои процедуры вызываются на каждую строку, естественно - никаких индексов?!! Более того, в зависимости от условий, одна и та же процедура фигурирует во вьюшке несколько раз, и, насколько я понял explain - informix так же тупо выполняет ее по нескольку раз на даже одну запись? не кэшируя результат?!

Получается, проще выкинуть все эти процедуры, и увязывать вьюшку напрямую с таблицами в каждой вьюшке - тогда, по-идее, оптимизатор сперва повыберет всякие id-категории клиента и потом ужЕ с ними будет сверять строки выираемой таблицы?

вот часть where из вьюшки:
where c.id=h.clientid and
((h.clientid=GetMyCid() and GetMyUCategory()='A')
or (c.parentid=GetMyCid() and (c.managerid=GetMyUid() or GetMyUCategory()='A')));

вот ее explain:

QUERY:
------
select * from v_payhistory

Estimated Cost: 3
Estimated # of Rows Returned: 1

1) informix.clients: SEQUENTIAL SCAN

2) informix.accpayhistory: INDEX PATH

Filters: ((informix.accpayhistory.clientid = informix.getmycid()AND informix.getmyucategory()= 'A' ) OR (informix.clients.parentid = informix.getmycid()AND (informix.clients.managerid = informix.getmyuid()OR informix.getmyucategory()= 'A' ) ) )

(1) Index Keys: clientid (Serial, fragments: ALL)
Lower Index Filter: informix.clients.id = informix.accpayhistory.clientid
NESTED LOOP JOIN

UDRs in query:
--------------
UDR id : 858
UDR name: getmyucategory
UDR id : 849
UDR name: getmyuid
UDR id : 850
UDR name: getmycid
UDR id : 858
UDR name: getmyucategory
UDR id : 850
UDR name: getmycid
...
Рейтинг: 0 / 0
30.05.2005, 16:15
    #33091057
В.К.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Два вопроса по оптимизации
1. Если сервер стоит на XP на процессоре p4 с гипертредингом (northwood 3.2).
Что указывать в MULTIPROCESSOR, NUMCPUVPS и SINGLE_CPU_VP ?
С одной стороны - процессор все же один. С другой - вроде как и не один...


Есть два принципиально разных варианта.

1.
MULTIPROCESSOR 0
NUMCPUVPS 1
SINGLE_CPU_VP 1

2.

MULTIPROCESSOR 1
NUMCPUVPS х
SINGLE_CPU_VP 0

где x - от 2 до 4 (2*типа_CPU)

Надо просто протестировать все четыре варианта на реальной нагрузке :)

По вопросу 2. Да, обычно не надо заменять функциями JOIN, тем более, если соединяется не сотня таблиц - пусть оптимизатор работает...
...
Рейтинг: 0 / 0
31.05.2005, 17:50
    #33093316
Ilya Kulagin
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Два вопроса по оптимизации
falcon111я сделал несколько процедур, типа getmyuid() getmycategory() getmystatus() и т.д.

..............

так же тупо выполняет ее по нескольку раз на даже одну запись? не кэшируя результат?!


Да, это штатное поведение. Если есть функция (к данному случаю сие не относится), значение которой зависит только от значения параметров и не зависит от содержимого таблиц базы, системного таймера и /dev/random, то в её описание надо добавить ключевое слово WITH NOT VARIANT. Тогда вычисляемое значение будет закешировано.
...
Рейтинг: 0 / 0
01.06.2005, 16:02
    #33095329
vasilis
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Два вопроса по оптимизации
falcon111...я сделал несколько процедур, типа getmyuid() getmycategory() getmystatus() и т.д. - все, что они делают - выбирают какое-либо поле из таблицы клиентов глядя на user сессии.
Посмотрел я на explain оптимизатора, который он выдает при выборке по подобной вьюшке - и ничего не понял. Я надеялся, что оптимизатор заставит сперва один раз отработать мои процедуры, и с их результатами сравнивать выбираемые строки пользуясь индексами, а получается, по-моему, что мои процедуры вызываются на каждую строку, естественно - никаких индексов?!! Более того, в зависимости от условий, одна и та же процедура фигурирует во вьюшке несколько раз, и, насколько я понял explain - informix так же тупо выполняет ее по нескольку раз на даже одну запись? не кэшируя результат?!

А как ты представляешь себе это - "кэшировать результат"?
Можно кэшировать план выполнения запроса, но не значение поля таблицы, к которой имеют доступ еще многие приложения.
Ведь сервер должен тебе гарантировать, что на момент обработки какой то 200-т тысячной строки через две минуты после начала обработки результат выполнения процедуры будет соответствовать реалиям настоящего момента, а не две минуты назад, ведь за эти две минуты в таблице могло ох как много измениться. "Многопользовательськая среда, сэр".
Если тебе чихать на такие тонкости, то выполни процедуры один раз, запомни их результат в переменной или временной таблице и используй эти значения как фильтр.
...
Рейтинг: 0 / 0
06.06.2005, 17:42
    #33103275
falcon111
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Два вопроса по оптимизации
Ilya Kulagin falcon111я сделал несколько процедур, типа getmyuid() getmycategory() getmystatus() и т.д.

..............

так же тупо выполняет ее по нескольку раз на даже одну запись? не кэшируя результат?!


Да, это штатное поведение. Если есть функция (к данному случаю сие не относится), значение которой зависит только от значения параметров и не зависит от содержимого таблиц базы, системного таймера и /dev/random, то в её описание надо добавить ключевое слово WITH NOT VARIANT. Тогда вычисляемое значение будет закешировано.

А можно с этого места подробнее? Я RTFM на этот предмет, и так понял, что это касается UDF, а не SPL.

А почему я не хочу делать join, а использую процедуры:
1. Более читабельный SQL-вьюшки, кроме того, если что-то менять в системе доступа - нужно один раз поменять соответствующую процедуру, а не лопатить все вьюшки, в которых это проверяется.
2. Вьюшка получается update-бельная, т.е. на нее можно выполнять insert/update/delete. Если вместо процедур сделать join с таблицами юзеров и проверять доступы прямо в теле view, то такая вью становится read-only, как вью, затрагивающая другие таблицы, а меня это не устраивает. :(

Есть ли какой-то способ по-человечески решить этот вопрос?
...
Рейтинг: 0 / 0
06.06.2005, 18:08
    #33103352
nkulikov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Два вопроса по оптимизации
2 vasilis: Кэширование значений может быть в том случае если у тебя при одних и тех же параметрах ф-ция выдает одно и тоже значение синус например. Значение синус от нуля сервер и кэширует. А если кто-то сказал серверу что функция значение которой зависит от кучи меняющихся данных возвращает одно и тоже значение сам себе злобный буратин :)
...
Рейтинг: 0 / 0
06.06.2005, 18:20
    #33103386
falcon111
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Два вопроса по оптимизации
vasilisА как ты представляешь себе это - "кэшировать результат"?
Можно кэшировать план выполнения запроса, но не значение поля таблицы, к которой имеют доступ еще многие приложения.
Ведь сервер должен тебе гарантировать, что на момент обработки какой то 200-т тысячной строки через две минуты после начала обработки результат выполнения процедуры будет соответствовать реалиям настоящего момента, а не две минуты назад, ведь за эти две минуты в таблице могло ох как много измениться. "Многопользовательськая среда, сэр".
Если тебе чихать на такие тонкости, то выполни процедуры один раз, запомни их результат в переменной или временной таблице и используй эти значения как фильтр.

Примерно так:
Если запрос выполняется в виде join с другой таблицей вместо процедуры, то оптимизатор выполняет запрос так - сперва выбирает id клиента по его сессии, затем этот ID сверяется с индексом выбираемой таблицы. Все быстро, все красиво.
И я рассчитывал, что с процедурой будет что-то подобное, что нужно посмотреть на процедуру, что она не зависит ни от одной другой таблицы запроса, следовательно в запросе она - константа, нужно вычислить эту константу, и по ее результатам использовать нидекс.

А если рассуждать так, что это типа многопользовательская среда, тогда индексы вообще использовать нельзя - ведь план выполнения строится так, что проверка доступа выбирается в начале, а потом по результату используется индекс большой таблицы. Кто-то точно так же может поменять таблицу юзеров, пока сервер выбирает записи из большой таблицы по индексу. Если рассуждать как ты, то индекс тоже нельзя использовать - нужно выбирать все записи, при этом постоянно проверяя таблицу юзеров.
Как мне кажется, - это перебор.
...
Рейтинг: 0 / 0
06.06.2005, 22:48
    #33103653
vasilis
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Два вопроса по оптимизации
falcon111
Примерно так:
Если запрос выполняется в виде join с другой таблицей вместо процедуры, то оптимизатор выполняет запрос так - сперва выбирает id клиента по его сессии, затем этот ID сверяется с индексом выбираемой таблицы. Все быстро, все красиво.
И я рассчитывал, что с процедурой будет что-то подобное, что нужно посмотреть на процедуру, что она не зависит ни от одной другой таблицы запроса, следовательно в запросе она - константа, нужно вычислить эту константу, и по ее результатам использовать нидекс.
Ну какая же она константа, если ЗАВИСИТ хоть от одной, но таблицы?
Ну представь, что твой запрос идет 10минут и за это время из таблицы удалили запись со всеми параметрами твоего UserID. Процедура все еще будет возвращать данные, которых уже просто не существует в природе?
Да и "посмотреть на процедуру" на предмет того, что она всегда вернет константу, довльно сложно - это такой анализатор надо строить, что мало не покажется... Но может я в чем то и неправ :)

falcon111 А если рассуждать так, что это типа многопользовательская среда, тогда индексы вообще использовать нельзя - ведь план выполнения строится так, что проверка доступа выбирается в начале, а потом по результату используется индекс большой таблицы. Кто-то точно так же может поменять таблицу юзеров, пока сервер выбирает записи из большой таблицы по индексу. Если рассуждать как ты, то индекс тоже нельзя использовать - нужно выбирать все записи, при этом постоянно проверяя таблицу юзеров.
Как мне кажется, - это перебор.
Так ведь проверяется :)
Посмотри Гуглем в конференции ukr.comp.dbms.informix топик "О скорости" за июль 2003 года - там описан интересный эксперимент, в котором видно сколько раз читается таблица sysusers (да еще и блокировки устанавливаются :) при работе рядового пользователя.
...
Рейтинг: 0 / 0
07.06.2005, 16:33
    #33105388
Ilya Kulagin
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Два вопроса по оптимизации
falcon111
А почему я не хочу делать join, а использую процедуры:
1. Более читабельный SQL-вьюшки, кроме того, если что-то менять в системе доступа - нужно один раз поменять соответствующую процедуру, а не лопатить все вьюшки, в которых это проверяется.


Когда мне понадобилось ограничить доступ к информации по транзакциям (Все транзакции хранятся в одной таблице. Однако, клиенту можно показывать только его транзакции. Точнее, транзакции по его счёту. Дополнительно бывает нужно ограничить его также некоторыми типами транзакций. Ну и ещё по ходу дела всякие условия придумываются), то самым простым способом оказалось написание процедуры, возвращающей готовый результат. Вариантов возврата результата два:

- непосредственно из процедуры, при этом данные не именованы и у некоторых средств разработки едет крыша

- во временной таблице, возможно, создаваемой самой процедурой. Тут надо предусмотреть возможность одновременного нескольких запросов внутри одной сессии. По крайней мере, для веб-интерфейса это крайне актуально. Во-вторых, данных может оказаться изрядно много.

Вот такой был опыт. Кстати, разрешения на select по таблицам при предоставлении данных посредством sp пользователю базы можно не давать. И даже connect можно не давать, если процедуры в отдельной database хранить.
...
Рейтинг: 0 / 0
08.06.2005, 09:33
    #33106388
genix
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Два вопроса по оптимизации
falcon111
А почему я не хочу делать join, а использую процедуры:
1. Более читабельный SQL-вьюшки, кроме того, если что-то менять в системе доступа - нужно один раз поменять соответствующую процедуру, а не лопатить все вьюшки, в которых это проверяется.
2. Вьюшка получается update-бельная, т.е. на нее можно выполнять insert/update/delete. Если вместо процедур сделать join с таблицами юзеров и проверять доступы прямо в теле view, то такая вью становится read-only, как вью, затрагивающая другие таблицы, а меня это не устраивает. :(

Есть ли какой-то способ по-человечески решить этот вопрос?

Я тоже свое время страдал этой фигней, и пришел к выводу, что использование такого вида:

CREATE VIEW v_bonus AS
SELECT * FROM bonus WHERE div_status in
(SELECT * FROM TABLE(get_dependent_id()));

работает гораздо быстрее, чем просто div_status=get_dependent_id()


Однако, увлекаться не стоит, ибо одна из разновидностей такого запроса просто роняет сервер (бага висит в IBM'е, говорят на 9.40UC6 тоже роняет)
...
Рейтинг: 0 / 0
Форумы / Informix [игнор отключен] [закрыт для гостей] / Два вопроса по оптимизации / 10 сообщений из 10, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]