Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Запрос, как поступить  [new]
Алексаша
Member

Откуда: Левый берег
Сообщений: 415
Здравствуйте!

такой вот запрос

SELECT *
FROM Table t
 LEFT JOIN нешустрая_функция() нф ON t.нф1=нф.id
выполняется приемлемо, практически нет задержки, до 1 сек., но стала необходимость в результате такого запроса

SELECT *
FROM Table t
 LEFT JOIN нешустрая_функция() нф ON t.нф1=нф.id
 LEFT JOIN нешустрая_функция() нф1 ON t.нф2=нф1.id

где нешустрая_функция() - ф-ция, возвращающая табличное значение

и вот тут уже не очень. Как правильно оформить запрос (чтобы ф-ция выполнялась один раз) чтобы время было так же как и в первом варианте ? Пробовал с помощью WITH результат то же. Как рационально?

Спасибо ....
29 дек 10, 21:27    [10019271]     Ответить | Цитировать Сообщить модератору
 Re: Запрос, как поступить  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Манипуляция генератором плана гиблое дело. Если вы-человек видите здесь чёрные ящики - аля "нешустрая_функция", то сервер их не видит, он палюбому сначала разворачивает весь запрос во всю глубину и лишь потом строит план, а как ни крути, но запрос особо не поменяется (при той же логике).
Вот вы "разверните" его сами и поймёте, что "абы как" тут не катит.

Всегда смотрите и курите планы. Повесите индекс, констрэйнт и план может вывернутся на изнанку.

C другой стороны у вас может быть "нешустрая_функция" table-valued, а не inline. Тогда ваще подход ошибочен. На крайняк подавайте id в качестве параметра.
29 дек 10, 22:03    [10019352]     Ответить | Цитировать Сообщить модератору
 Re: Запрос, как поступить  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Алексаша,
м.б. имеет смысл результаты работы нешустрой функции занести во временную таблицу или табличную переменную предварительно и в основном запросе уже использовать таблицу а не функцию.
29 дек 10, 22:08    [10019367]     Ответить | Цитировать Сообщить модератору
 Re: Запрос, как поступить  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31965
Алексаша
но стала необходимость в результате такого запроса

SELECT *
FROM Table t
 LEFT JOIN нешустрая_функция() нф ON t.нф1=нф.id
 LEFT JOIN нешустрая_функция() нф1 ON t.нф2=нф1.id

где нешустрая_функция() - ф-ция, возвращающая табличное значение

и вот тут уже не очень. Как правильно оформить запрос (чтобы ф-ция выполнялась один раз) чтобы время было так же как и в первом варианте ? Пробовал с помощью WITH результат то же. Как рационально?

Спасибо ....
А так не быстрее?
SELECT *
FROM Table t
 LEFT JOIN нешустрая_функция() нф ON нф.id in (t.нф1, t.нф2)
29 дек 10, 22:16    [10019390]     Ответить | Цитировать Сообщить модератору
 Re: Запрос, как поступить  [new]
Алексаша
Member

Откуда: Левый берег
Сообщений: 415
alexeyvg
А так не быстрее?
SELECT *
FROM Table t
 LEFT JOIN нешустрая_функция() нф ON нф.id in (t.нф1, t.нф2)


может и быстрее, но не подходит :)
при такое реализации нельзя сделать так

SELECT нф.поле+нф1.поле
FROM Table t
 LEFT JOIN нешустрая_функция() нф ON t.нф1=нф.id
 LEFT JOIN нешустрая_функция() нф1 ON t.нф2=нф1.id
29 дек 10, 23:33    [10019571]     Ответить | Цитировать Сообщить модератору
 Re: Запрос, как поступить  [new]
iljy
Member

Откуда:
Сообщений: 8711
Алексаша,

тогда создайте временную таблицу и сделайте в нее выборку из функции. На таблице сделайте кластерный индекс по ид.
29 дек 10, 23:57    [10019647]     Ответить | Цитировать Сообщить модератору
 Re: Запрос, как поступить  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31965
Алексаша
может и быстрее, но не подходит :)
при такое реализации нельзя сделать так

SELECT нф.поле+нф1.поле
FROM Table t
 LEFT JOIN нешустрая_функция() нф ON t.нф1=нф.id
 LEFT JOIN нешустрая_функция() нф1 ON t.нф2=нф1.id
Тут зависит от конкретного запроса.

Возможно, получится нф.поле+нф1.поле заменить на sum(нф.поле)
30 дек 10, 00:37    [10019743]     Ответить | Цитировать Сообщить модератору
 Re: Запрос, как поступить  [new]
Алексаша
Member

Откуда: Левый берег
Сообщений: 415
alexeyvg
Алексаша
может и быстрее, но не подходит :)
при такое реализации нельзя сделать так

SELECT нф.поле+нф1.поле
FROM Table t
 LEFT JOIN нешустрая_функция() нф ON t.нф1=нф.id
 LEFT JOIN нешустрая_функция() нф1 ON t.нф2=нф1.id
Тут зависит от конкретного запроса.

Возможно, получится нф.поле+нф1.поле заменить на sum(нф.поле)


Хм. хороший пример возьму на вооружение. Но мне надо текстовые данные конкетировать

А помогло использование табличной переменной.

SomewhereSomehow, спасибо.
30 дек 10, 10:06    [10020451]     Ответить | Цитировать Сообщить модератору
 Re: Запрос, как поступить  [new]
Алексаша
Member

Откуда: Левый берег
Сообщений: 415
Здравствуйте! Тут мне советовали использование временной таблицы, поэтому решил задать вопрос здесь.

Обрисую ситуацию: есть БД в ней функции и процедуры, которые в своем коде обращаются к нешустрая_функция()

Возможно ли сделать так, чтоб выше описанные функции и процедуры обращались к временной таблице, содержащей результат выполнения нешустрая_функция(). А временная табл. создается при первой необходимости, т.е. если ее нет она создается, если есть то не создается.

Извините, если не внятно изложил вопрос, уточню если что ....

Спасибо ....
5 янв 11, 01:05    [10034475]     Ответить | Цитировать Сообщить модератору
 Re: Запрос, как поступить  [new]
Glory
Member

Откуда:
Сообщений: 104751
Алексаша

Возможно ли сделать так, чтоб выше описанные функции и процедуры обращались к временной таблице, содержащей результат выполнения нешустрая_функция(). А временная табл. создается при первой необходимости, т.е. если ее нет она создается, если есть то не создается.

В функциях обращения к временным таблицам запрещены
5 янв 11, 14:59    [10035500]     Ответить | Цитировать Сообщить модератору
 Re: Запрос, как поступить  [new]
Алексаша
Member

Откуда: Левый берег
Сообщений: 415
Glory
В функциях обращения к временным таблицам запрещены


Понятно .... значит отпадает
5 янв 11, 17:48    [10036046]     Ответить | Цитировать Сообщить модератору
 Re: Запрос, как поступить  [new]
iljy
Member

Откуда:
Сообщений: 8711
Алексаша,

а создать постоянную таблицу этой нешустрой функцией не? И периодически ее пересоздавать заданием.
5 янв 11, 21:01    [10036453]     Ответить | Цитировать Сообщить модератору
 Re: Запрос, как поступить  [new]
Алексаша
Member

Откуда: Левый берег
Сообщений: 415
iljy
Алексаша,

а создать постоянную таблицу этой нешустрой функцией не? И периодически ее пересоздавать заданием.


Возьму на заметку
8 янв 11, 13:16    [10042080]     Ответить | Цитировать Сообщить модератору
 Re: Запрос, как поступить  [new]
aleks2
Guest
Ежели выполнение
SELECT *
FROM Table t
 LEFT JOIN нешустрая_функция() нф ON t.нф1=нф.id
1 секунда, то

SELECT *
FROM Table t
 LEFT JOIN нешустрая_функция() нф ON t.нф1=нф.id
 LEFT JOIN нешустрая_функция() нф1 ON t.нф2=нф1.id
должно быть максимум 3 секунды.

Отсель вывод: покажите ОПРЕДЕЛЕНИЕ нешустрая_функция() и вам полегчает безо фсяких извращений.
8 янв 11, 13:27    [10042098]     Ответить | Цитировать Сообщить модератору
 Re: Запрос, как поступить  [new]
лолл
Member

Откуда:
Сообщений: 450
Алексаша,

еще вариант: послать нафиг нешуструю функцию, написать вместо ее представление. Если это невозможно или невыгодно по каким-либо причинам, то можно заменить функцию процедурой, которая содержала бы весь алгоритм получения данных функции + записывала бы эти данные во внешнюю временную таблицу.
8 янв 11, 13:34    [10042116]     Ответить | Цитировать Сообщить модератору
 Re: Запрос, как поступить  [new]
Алексаша
Member

Откуда: Левый берег
Сообщений: 415
лолл
Алексаша,

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


а разве у представления есть преимущество по скорости перед функцией возвращающей табл. значение? если я код нешустрой_ф-ции помещу в представление то в моем случае все равно код будет выполнятся 2 раза, ведь так?
8 янв 11, 14:15    [10042183]     Ответить | Цитировать Сообщить модератору
 Re: Запрос, как поступить  [new]
iljy
Member

Откуда:
Сообщений: 8711
Алексаша
а разве у представления есть преимущество по скорости перед функцией возвращающей табл. значение? если я код нешустрой_ф-ции помещу в представление то в моем случае все равно код будет выполнятся 2 раза, ведь так?

Перед инлайн-функцией - нет.
8 янв 11, 14:22    [10042191]     Ответить | Цитировать Сообщить модератору
 Re: Запрос, как поступить  [new]
Алексаша
Member

Откуда: Левый берег
Сообщений: 415
iljy
Алексаша
а разве у представления есть преимущество по скорости перед функцией возвращающей табл. значение? если я код нешустрой_ф-ции помещу в представление то в моем случае все равно код будет выполнятся 2 раза, ведь так?

Перед инлайн-функцией - нет.


извините :) что значит инлайн-функция
8 янв 11, 14:54    [10042247]     Ответить | Цитировать Сообщить модератору
 Re: Запрос, как поступить  [new]
iljy
Member

Откуда:
Сообщений: 8711
Алексаша,

Inline User-Defined Functions
8 янв 11, 14:58    [10042250]     Ответить | Цитировать Сообщить модератору
 Re: Запрос, как поступить  [new]
Алексаша
Member

Откуда: Левый берег
Сообщений: 415
iljy
Алексаша,

Inline User-Defined Functions


если я правильно понял inline-функция - функция возвращающая табл. значение, код которой не многооператорный.

Значит если нешустрая_ф-ция () - многооператорная то ее код лучше оформить в виде представления, правильно я понял?
8 янв 11, 15:26    [10042299]     Ответить | Цитировать Сообщить модератору
 Re: Запрос, как поступить  [new]
iljy
Member

Откуда:
Сообщений: 8711
Алексаша
Значит если нешустрая_ф-ция () - многооператорная то ее код лучше оформить в виде представления, правильно я понял?

Очень интересно посмотреть. как вы это сделаете.
Попробуйте функцию переписать как инлайн, быстродействие может существенно улучшится.
8 янв 11, 15:29    [10042306]     Ответить | Цитировать Сообщить модератору
 Re: Запрос, как поступить  [new]
Алексаша
Member

Откуда: Левый берег
Сообщений: 415
Понятно ....

Я начал делать глупо - использовать в представлении ф-ции инлайн, короче из пустого в порожнее
8 янв 11, 15:38    [10042325]     Ответить | Цитировать Сообщить модератору
 Re: Запрос, как поступить  [new]
Алексаша
Member

Откуда: Левый берег
Сообщений: 415
т.е. не инлайн - Multi-statement
8 янв 11, 15:39    [10042328]     Ответить | Цитировать Сообщить модератору
 Re: Запрос, как поступить  [new]
aleks2
Guest
Алексаша
т.е. не инлайн - Multi-statement


Гюльчатай, открой личико!

Тьфу... чОрт!

Функцию В СТУДИЮ!

PS. Готов поспорить, что тредстартер не ведает об индексах на табличных переменных.
8 янв 11, 17:56    [10042645]     Ответить | Цитировать Сообщить модератору
 Re: Запрос, как поступить  [new]
Andrey Sribnyak
Member

Откуда: Киев
Сообщений: 600
aleks2

PS. Готов поспорить, что тредстартер не ведает об индексах на табличных переменных.


А на табличные переменные можно установить индексы? :-)
9 янв 11, 10:01    [10044467]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить