Форум: "Прочее";
Текущий архив: 2010.12.26;
Скачать: [xml.tar.bz2];
ВнизКак сделать один SQLзапрос, но чтобы вложения считались единожды? Найти похожие ветки
← →
И. Павел © (2010-09-15 11:47) [0]Здравствуйте.
У меня есть запрос вида:SELECT …
FROM …
INNER JOIN …
LEFT JOIN …
…
WHERE user_field IN (SELECT user_item FROM user_list WHERE id > :PID1) AND date_field > DATEADD(days, (SELECT date_item FROM date_list WHERE id = :PID2), :PDate) AND …
При этом выборка (SELECT user_item FROM user_list WHERE id > :PID1) и величина (SELECT date_item FROM date_list WHERE id = :PID2) одинаковы для всех записей. Но запрос выполняется долго, видимо из-за того, что эти вложенные SELECT-ы выполняются для каждой записи, для проверки – стоит ли ее включать в конечную выборку. Это было бы не так страшно, если бы user_field не был строкой (базу не я проектировал)… В результате запрос с Where выполняется в 3 раза медленнее, чем без where.
Подскажите, пожалуйста, можно ли, и, если можно, то как сделать выборку user_item и значения date_item один раз и использовать их в этом запросе, но без непосредственного создания временной таблицы и переменной через TSQL. Т.е. я хотел бы сделать это все в одном запросе.
PS: Использую MS SQL 2005, а WITH там нет.
Заранее спасибо.
← →
12 © (2010-09-15 12:01) [1]WHERE user_field IN (SELECT user_item FROM user_list WHERE id > :PID1)
заменить на еще один join
join user_list UL on UL.user_item = WHO.user_field
+
WHERE
UL.id > :PID1
← →
Anatoly Podgoretsky © (2010-09-15 12:01) [2]> И. Павел (15.09.2010 11:47:00) [0]
> PS: Использую MS SQL 2005, а WITH там нет.
Кто украл? Да в 2005 этих WITH как в Бразилии диких обезьян.
> If a calculated member is only required for a single Multidimensional
> Expressions (MDX) query, you can define that calculated member by using
> the WITH keyword. A calculated member that is created by using the WITH
> keyword no longer exists after the query has finished running.
← →
И. Павел © (2010-09-15 12:22) [3]> Кто украл? Да в 2005 этих WITH как в Бразилии диких обезьян.
Спасибо. Я спутался - когда мне не хватало with я был в SQL 2000 :) Через него сделаю.
> [1] 12 © (15.09.10 12:01)
Спасибо. Но т.к. user_item-ов для одной записи может быть несколько, то получится, что число записей возрастет во столько раз, сколько выбралось user_item. И как проанализировать их я не знаю...
PS: Ну вот зачем разработчики базы использовали текстовые "индексы" (причем строки не маленькие) мне не понятно... Все равно так получится в разы медленнее, чем с числовыми.
← →
И. Павел © (2010-09-15 13:09) [4]> WITH ui AS (SELECT * FROM USERLIST.dbo.UserInf) SELECT * FROM USERLIST.dbo.UserInf
Такой запрос нормально выполняетмя в SQL SERVER MANAGER, но при использовании в ADODataSet или ADOQuery возвращает ошибку: "Incorrect syntax near the keyword "with"". Подскажите, пожалуйста, почему ADO рушается на запрос?
← →
И. Павел © (2010-09-15 13:09) [5]рушается -> ругается
← →
Ega23 © (2010-09-15 13:11) [6]напиши хранимку, они для этого и предназначены.
← →
b z (2010-09-15 13:14) [7]
> WITH ui AS
А если;WITH ui AS ...
?
← →
Anatoly Podgoretsky © (2010-09-15 13:19) [8]> И. Павел (15.09.2010 13:09:04) [4]
Справка говорит, что In the syntax for the WITH keyword, the
Member_Identifier value is the fully qualified name of the calculated
member.
В примерах по крайней мере так.
← →
И. Павел © (2010-09-15 14:06) [9]Всем большое спасибо.
> А если ;WITH ui AS ... ?
Спасибо. Так работает :) Насколько я понимаю, это обман ADO? Тот проверяет синтаксис до первой ";"?
PS: похоже, медленная работа запроса связана не с SELECT user_item и даже не с вызовом функции DateAdd. С Width получается даже немного медленнее. Единственное - поставлю проверку даты вперед, чтобы проверялся только первый операнд ADD и отсеивалась большая часть записей. Просто в таблицах записей много, и они все связываются через JOIN, а быстрее, чем 30 запросов в секунду все равно не выдается.
← →
Ega23 © (2010-09-15 14:15) [10]
> Единственное - поставлю проверку даты вперед, чтобы проверялся
> только первый операнд ADD и отсеивалась большая часть записей.
Это за тебя сделает оптимизатор. Менять порядок имеет смысл только в плане управления индексами.
← →
b z (2010-09-15 14:18) [11]
> Насколько я понимаю, это обман ADO? Тот проверяет синтаксис
> до первой ";"?
http://msdn.microsoft.com/en-us/library/ms175972.aspx
> When a CTE is used in a statement that is part of a batch,
> the statement before it must be followed by a semicolon.
Профайлером посмотрите реальный запрос.
← →
Anatoly Podgoretsky © (2010-09-15 14:20) [12]> И. Павел (15.09.2010 14:06:09) [9]
Ты плохо думаешь об сервере, нормальному серверу все равно, он строит свой
план.
← →
wicked © (2010-09-15 15:09) [13]первое и самое главное - переписать запрос так, чтобы вместо IN было EXISTS
потом уже можно смотреть на планы и оптимизировать их
← →
И. Павел © (2010-09-15 15:29) [14]> Ты плохо думаешь об сервере, нормальному серверу все равно,
> он строит свой
> план.
Все верно. Как не переставлял все местами, время не изменилось... Слишком умный сервер - нельзя в случае чего соптимизировать.
Единственное - функцию DateAdd все же выполняет заново для каждой строки, так что я ее сперва просчитаю отдельным запросом.
← →
Ega23 © (2010-09-15 15:39) [15]
> Слишком умный сервер - нельзя в случае чего соптимизировать.
Кто сказал, что нельзя? Просто выпрями руки, пересади их в плечи и читай про индексы.
← →
И. Павел © (2010-09-15 15:44) [16]>[15] Ega23 © (15.09.10 15:39)
База не моя. Я же писал. Моя программа просто выполняет небольшие сервисные функции.
> [13] wicked © (15.09.10 15:09)
Спаисбо за вариант. Но при замене на Exists время осталось то же.
Страницы: 1 вся ветка
Форум: "Прочее";
Текущий архив: 2010.12.26;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.004 c