Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Вопрос по быстродействию,... курсоры или ..... (MS SQL 2000) / 18 сообщений из 18, страница 1 из 1
20.12.2001, 10:46
    #32019415
XDefender
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по быстродействию,... курсоры или ..... (MS SQL 2000)
Вопрос по быстродействию.
Что будет быстрее:



declare @ID int

if (select count(ID) from #TMP)>0
BEGIN
set @ID=(select top 1 ID from #TMP)
exec UpdateTransactionLog @ID, @Type
delete from #TMP
where ID=@ID
END

или с использованием курсора, просто со скролингом, без удаления??
т.е.

DECLARE @MYC CURSOR LOCAL FAST_FORWARD
FOR Select * from #TEMP

OPEN @MYC

FETCH @MYC INTO @ID
WHILE .....
exec UpdateTransactionLog @ID, @Type
FETCH @MYC INTO @ID

CLOSE @MYC
DEALOCATE @MYC
...
Рейтинг: 0 / 0
20.12.2001, 13:25
    #32019446
Cursor
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по быстродействию,... курсоры или ..... (MS SQL 2000)
А что говорит QA, что быстрее исполняется?
...
Рейтинг: 0 / 0
20.12.2001, 17:04
    #32019472
Вопрос по быстродействию,... курсоры или ..... (MS SQL 2000)
Вообще-то именно здесь курсор может работать быстрее.
Но на самом деле это неважно, посколько я вижу здесь совершенно ужасный приём - использование временных таблиц в SQL2000 смерти подобно.
Очень рекомендую перейти на использование переменных типа table, почему - читайте в KB. Кратко - временные таблицы ухудшают работу оптимизатора.
...
Рейтинг: 0 / 0
21.12.2001, 07:15
    #32019511
SergSuper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по быстродействию,... курсоры или ..... (MS SQL 2000)
если посмотреть повнимательнее то, сразу будет понятно что первый вариант будет работать адназначна быстрее - в первом варианте просто условие(if), а во втором цикл

Если серьёзно(я конечно понимаю что вместо if имеется ввиду while), то я, хоть и противник курсоров, остановился бы на 2-м варианте. Хотя большой разницы между вариантами не вижу.

Приведенное выше замечание, что "использование временных таблиц в SQL2000 смерти подобно" поскольку это "ухудшает работу оптимизатора" высказанно, очевидно, не подумав - временная таблица здесь используется просто как небольшой массив данных и в запросах, где требуется оптимизация не участвует.
...
Рейтинг: 0 / 0
21.12.2001, 07:35
    #32019512
Вопрос по быстродействию,... курсоры или ..... (MS SQL 2000)
Временные таблицы - одна из ключевых особенностей T-SQL. Рекомендовать их не использовать, тоже самое что рекомендовать не использовать GROUP BY в запросе. Кто будет возражать против утверждения, что GROUP BY приводит к дополнительным накладным расходам и замедляет запрос? Однако отказываться от него никто не рекомендует по очевидным соображениям.

Хочу напомнить Акжану, что сервер сам интенсивно использует временные таблицы для сортировки, группировки и хранения промежуточных данных при исполнении сложных запросов.

Другое дело, что временные таблицы должны использоваться осмысленно, к месту.
...
Рейтинг: 0 / 0
21.12.2001, 07:38
    #32019513
Вопрос по быстродействию,... курсоры или ..... (MS SQL 2000)
Переменная типа TABLE - это, конечно, классно. Однако не всегда можно временную таблицу заменить таблицей-переменной.

Попробуйте, например, сделать SELECT INTO в таблицу-переменную.
...
Рейтинг: 0 / 0
21.12.2001, 07:56
    #32019515
Александр Степанов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по быстродействию,... курсоры или ..... (MS SQL 2000)
Буду исходить из того, что в первом варианте вместо IF имелся в виду WHILE. Из-за того, что в первом варианте в цикле из временной таблицы будут удаляться строки, он будет выполняться однозначно медленнее, особенно при увеличении кол-ва записей во временной таблице.
...
Рейтинг: 0 / 0
21.12.2001, 09:34
    #32019525
alexeyvg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по быстродействию,... курсоры или ..... (MS SQL 2000)
Ну первый вариант можно оптимизировать:
declare @ID int
WHILE 1=1
BEGIN
select @ID=ID from #TMP
if @@rowcount = 0 break
exec UpdateTransactionLog @ID, @Type
delete from #TMP
where ID=@ID
END
...
Рейтинг: 0 / 0
21.12.2001, 09:41
    #32019527
qu-qu
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по быстродействию,... курсоры или ..... (MS SQL 2000)
А никто не задумывался о том, что выражение типа
delete from #TMP
where ID=@ID - будет сканировать таблицу #TMP до нахождения нужного ID (никто же не строит временный индекс на небольшом временном наборе данных) ровно столько раз сколько записей в этой таблице?

При использовании курсора - то же самое сканирование происходит всего 1 раз... (собственно - "пробежка" по курсору).

Хотя, я так же как и большинство присутствующих - ненавижу курсоры в MS-SQL, но похоже, что второй способ все-таки быстрее...

А для "успокоения души" по поводу использования первого способа - можно предположить, что на второй-третьей итерации цикла вся временная табличка (если она действительно небольшая) будет закеширована в оперативку, и разница в скорости обработки цикла, по сравнению с "пробежкой" по курсору, уже не будет столь критична... ИМХО.
...
Рейтинг: 0 / 0
21.12.2001, 10:11
    #32019536
XDefender
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по быстродействию,... курсоры или ..... (MS SQL 2000)
Пишет автор этого сообщения: Ч-Defender
Вот что я хочу сказать.

declare @ID int
WHILE 1=1
BEGIN
select @ID=ID from #TMP
if @@rowcount = 0 break
exec UpdateTransactionLog @ID, @Type
delete from #TMP
where ID=@ID
END

Доволно неплох..
Хотя при больших таблицах (больше 30 записей) лучше (на мой взгляд) пользоваться курсором.
Просто в таблице #TMP самое вероятное количество записей - 4 (обычно от 1 до 12).

Я эту таблицу создаю из хранимой процедуры... SELECT ID INTO #TMP FROM INSERTED и затем запускаю хранимую процедуру, обработку этой таблицы.
...
Рейтинг: 0 / 0
21.12.2001, 10:15
    #32019539
XDefender
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по быстродействию,... курсоры или ..... (MS SQL 2000)
А таблица действительно кэшируется в память.... в MS SQL 2000, и притом сразу при создании, особенно из тригера.
...
Рейтинг: 0 / 0
21.12.2001, 11:01
    #32019553
Genady
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по быстродействию,... курсоры или ..... (MS SQL 2000)
Странный спор какой то

Насколько я понял народ желает понять что будет выполнятся быстрее цикл по таблице(с построчной выборкой) или курсор.
Так вот в этой ситуации курсор однозначно быстрее, где то здесь есть ветка за Апрель кажется, где тоже подобная тема была, там автор утверждал, что цикл по таблице быстрее и я проводил тест и сравнивал (вообще то зря конечно, и так ведь ясно, что цикл по таблице это тот же курсор, только самопальный) и естественно курсор был быстрее. А кэшируется при этом таблица или нет не так уж важно.
...
Рейтинг: 0 / 0
21.12.2001, 11:19
    #32019559
XDefender
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по быстродействию,... курсоры или ..... (MS SQL 2000)
Да, но ведь нужно учесть, что на создание курсора уходит куча времени....
...
Рейтинг: 0 / 0
26.12.2001, 14:33
    #32019880
Вопрос по быстродействию,... курсоры или ..... (MS SQL 2000)
Всем заинтересованным лицам рекомендую произвести простейшую проверку:
Дело в том, что классические временные таблицы (#) в MS SQL 2000 очень тяжело сказываются на оптимизаторе. Вот цитата из MSDN:
Use table variables instead of temporary tables, whenever possible. table variables provide the following benefits:

A table variable behaves like a local variable. It has a well-defined scope, which is the function, stored procedure, or batch in which it is declared.
Within its scope, a table variable may be used like a regular table. It may be applied anywhere a table or table expression is used in SELECT, INSERT, UPDATE, and DELETE statements. However, table may not be used in the following statements:

INSERT INTO table_variable EXEC stored_procedure

SELECT select_list INTO table_variable statements.

table variables are cleaned up automatically at the end of the function, stored procedure, or batch in which they are defined.

table variables used in stored procedures result in fewer recompilations of the stored procedures than when temporary tables are used.


Transactions involving table variables last only for the duration of an update on the table variable. Thus, table variables require less locking and logging resources.


Можете проверить на хорошо загруженном сервере предыдущий вариант с #, и вариант с нормальной переменной типа TABLE:

DECLARE @ops TABLE(
"Id" INT NOT NULL PRIMARY KEY
)

DECLARE @Id INT

INSERT
INTO @ops
SELECT "Id" FROM ....

WHILE 1=1
BEGIN
SELECT TOP 1 @Id = "Id" FROM @ops ORDER BY "Id" DESC
IF @Id IS NULL BREAK
...
DELETE FROM @ops WHERE ("Id" = @Id)
END
...
Рейтинг: 0 / 0
26.12.2001, 17:14
    #32019892
alexeyvg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по быстродействию,... курсоры или ..... (MS SQL 2000)
2Акжан Абдулин
В Вашем примере стэйтмент SELECT TOP 1 @Id = "Id" FROM @ops ORDER BY "Id" DESC создаёт ещё одну временную таблицу. Но уже в в цикле, много раз.
Вот если без ORDER BY, тогда можно и тестировать...
На СКУЭЛЬ 6.5 такой способ был намного быстрее курсоров, а с 7-й версии курсоры улучшились, теперь он примерно такой-же или только чуть быстрее.
...
Рейтинг: 0 / 0
27.12.2001, 07:44
    #32019910
Вопрос по быстродействию,... курсоры или ..... (MS SQL 2000)
2 Акжан Абдулин

Конечно, никто не спорит, что по возможности надо вместо временных таблиц использовать переменные таблицы. Однако, это справедливо только для небольших объемов. Для больших объемов данных, как уже здесь обсуждалось (не помню, чей копирайт, сорри), все наоборот. Кроме того, замена временных таблиц таблицами-переменными не всегда возможна. Она просто невозможна в следующих случаях:
1. Когда временная таблица (ранее созданная) используется во вложенной процедуре.
2. В выражении INSERT EXEC
3. При использовании временной таблицы (ранее созданной) в динамическом запросе.
4. Когда код должен работать не только в версии MSSQL2000, но и в предыдущей.
5. В выражении SELECT INTO

Я думаю, список этим не ограничивается.
...
Рейтинг: 0 / 0
27.12.2001, 15:00
    #32019956
Вопрос по быстродействию,... курсоры или ..... (MS SQL 2000)
2 Глеб Уфимцев:
С Вашими замечаниями согласен.
Единственное, что мои SELECT ORDER BY не делает новой временной таблицы, так как таблица-переменная создана с первичным ключом. Здесь ORDER BY используется для возможной оптимизации удаления записей из таблицы-переменной. Не проверял, даёт это какой-либо эффект, но отрицательно точно не сказывается.
...
Рейтинг: 0 / 0
27.12.2001, 17:37
    #32019966
alexeyvg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по быстродействию,... курсоры или ..... (MS SQL 2000)
Деёствительно, с ORDER BY быстрее!!!
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Вопрос по быстродействию,... курсоры или ..... (MS SQL 2000) / 18 сообщений из 18, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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