Вопросы
1) есть таблица, там два поля есть. Записи часто обновляются Кроме того, часто происходит поиск по обоим полям одновременно и по первому полю.
Намного ли лучше будет, если создать индекс из двух полей и индекс из первого поля?
или инднеса из двух полей достаточно?
2) Подскажите, как опитимизировать запрос
Update A set x1 = @@value where id in (select top 100 id from A where x1 is null and x2=@criteria order by x3)
Есть иднесы на id, x1 и x2, x3
Работает медленно, при этом
set transaction isolation level read uncommitted
Update A set x1 = @@value where id in (select top 100 id from A where x1 is null and x2=@criteria order by x3)
Есть иднесы на id, x1 и x2, x3
работает быстрее, чем
set transaction isolation level read uncommitted
Update A set x1 = @@value where id in (select top 100 id from A with (nolock) where x1 is null and x2=@criteria order by x3)
Есть иднесы на id, x1 и x2, x3
— также неясно, почему
3)
Есть ли разница в работе простой транзакции
INSERT INTO A (x1,x2) values (@x1,@x2)
в зависимости от уровня изолированности, на котором она работает? кажется, нету, верно ли?
Заранее спасибо!
Во втором запросе во втором варианте конечно без set transaction isolation level read uncommitted, опечатался
Здравствуйте, Albatross, Вы писали:
A>Вопросы
A>1) есть таблица, там два поля есть. Записи часто обновляются Кроме того, часто происходит поиск по обоим полям одновременно и по первому полю.
A>Намного ли лучше будет, если создать индекс из двух полей и индекс из первого поля?
A>или инднеса из двух полей достаточно?
трудно не зная тип полей, их уникальность, как задаются условия (точное значение или диапазон)...
возможно будет вполне оптмальным по первому полю сделать кластерный индекс, и добавить индекс с двумя полями, где первое поле стоит вторым
A>2) Подскажите, как опитимизировать запрос
A>A>Update A set x1 = @@value where id in (select top 100 id from A where x1 is null and x2=@criteria order by x3)
A>
попробовать использовать табличную переменную:
set transaction isolation level read COMMITTED
begin tran
declare @tmp table (id int)
insert @tmp select top 100 id from A with(readpast, rowlock, updlock) where x1 is null and x2=@criteria order by x3
update t set x1 = @value
from @tmp t2 join A t with(rowlock) on t2.id = t.id
commit
A>Есть иднесы на id, x1 и x2, x3
A>Работает медленно, при этом
A>A>set transaction isolation level read uncommitted
A>Update A set x1 = @@value where id in (select top 100 id from A where x1 is null and x2=@criteria order by x3)
A>Есть иднесы на id, x1 и x2, x3
A>
A>работает быстрее, чем
A>A>set transaction isolation level read uncommitted
A>Update A set x1 = @@value where id in (select top 100 id from A with (nolock) where x1 is null and x2=@criteria order by x3)
A>Есть иднесы на id, x1 и x2, x3
A>
— также неясно, почему
то что есть одиночные индексы мало о чем говорит (скорее всего идет посторение пересечения индексов или вообще сканирование), нужно смотреть планы. а в чем выражается "быстрее"? нужна точная статистика
A>3)
A>Есть ли разница в работе простой транзакции
A>A>INSERT INTO A (x1,x2) values (@x1,@x2)
A>
A>в зависимости от уровня изолированности, на котором она работает? кажется, нету, верно ли?
на мой взгляд не стоит играть с общим уровнем изоляции, лучше осознано задавать hint для каждой таблицы в запросе
A>Заранее спасибо!
Здравствуйте, Albatross, Вы писали:
А вы посмотрите план выполнения наиболее часто используемых запросов с различными индексами. Тут еще имеет значение кластерные они будут или нет (тоже от типа запросов зависит). Да и статистику можно посмотреть — сколько он там страниц просматривает.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Здравствуйте, Albatross, Вы писали:
A>Есть иднесы на id, x1 и x2, x3
A>Работает медленно
Ну естественно медленно! План запроса посмотри — ужаснешься. Потом добавь индекс по (x1, x2, x3, id) и посмотри, как оно полетит.
Играть с уровнями изоляции не надо — проблема не в них. Всегда смотри в план запроса!

1.2.0 alpha rev. 655
Albatross пишет:
> 1) есть таблица, там два поля есть. Записи часто обновляются Кроме того,
> часто происходит поиск по обоим полям одновременно и по первому полю.
> Намного ли лучше будет, если создать индекс из двух полей и индекс из
> первого поля?
> или инднеса из двух полей достаточно?
Индекса (ПЕРВОЕ ПОЛЕ, ВТОРОЕ ПОЛЕ) будет достаточно для всех вариантов поиска.
Но если второе поле при фиксированном значении первого поля обладает низкой
селективностью (например, при фиксированном первом поле второе имеет 1, 2, 3
значения), то возможно лучшим будет индекс только на ПЕРВОЕ ПОЛЕ.
Ну и конечно все это имеет смысл только если в таблице большое количество
разных значений первого поля.
> 2) Подскажите, как опитимизировать запрос
>
> Update A
>set x1 = @@value
>where id in (select top 100 id
> from A where x1 is null and x2=@criteria order by x3)
>
Да никак, если либо
записей с x1 is null
либо с x2=@criteria
мало, и на них есть соотв. индексы, то
вполне себе хороший запрос получается.
> Есть иднесы на id, x1 и x2, x3
Наличие всех трех индексов на x1, x2, x3 для
данного запроса излишне. Все равно будет использоваться
только один (если не один — это будет еще хуже).
Индекс по x3 очень сомнительно что будет полезен,
поскольку он мог бы быть полезен только для
ORDER BY, при этом сервер будет бежать по
нему , обрабатывая всю таблицу, отбрасывая записи,
не удовлетворяющие x1 is null and x2=@criteria,
пока не наберет 100 записей. Ну очень сомнительная
стратегия. Так что я бы индекс по x3 дропнул, если
он конечно для чего-то другого не нужен.
> Работает медленно, при этом
> set transaction isolation level read uncommitted
А бесполезно. Update на dirty read работать все равно
не сможет, а для подзапроса, если он быстро отрабатывать
будет, ему все одно, что read uncommitted, что read committed.
> Update A set x1 = @@value where id in (select top 100 id from A where x1 is null and x2=@criteria order by x3)
А я вот не понял, в чем отличие. Я его не вижу.
> set transaction isolation level read uncommitted
> Update A set x1 = @@value where id in (select top 100 id from A with (nolock) where x1 is null and x2=@criteria order by x3)
> Есть иднесы на id, x1 и x2, x3
Т.е. индексы те же ?
with (nolock) — это и есть read uncommitted. Это просто два способа
добится одного и того же эффекта.
> — также неясно, почему
Когда ты ставишь transaction isolation level read uncommitted,
сервер должен читать данные в особом режиме, без блокировок
(собственно он не обязан, но MSSQL работает именно так).
Это влияет на выбор способов доступа к данным, а именно,
возможно некоторые виды доступа не смогут быть применены.
Т.е. это напрямую влияет на выборы оптимизатора, с чем, возможно,
ты и сталкиваешься. Но возможно тут действуют еще какие-то факторы.
Мой совет — не ставить transaction isolation level read uncommitted,
работать на дефолтном read committed.
> 3)
> Есть ли разница в работе простой транзакции
>
> INSERT INTO A (x1,x2) values (@x1,@x2)
> в зависимости от уровня изолированности, на котором она работает?
> кажется, нету, верно ли?
Если коротко и упрощенно — нет.
Posted via RSDN NNTP Server 2.0
Sinclair пишет:
> Ну естественно медленно! План запроса посмотри — ужаснешься. Потом
> добавь индекс по (x1, x2, x3, id) и посмотри, как оно полетит.
Такой составной индекс вряд ли нужен.
И кластерный обычно в MSSQL делают по PK
(который тут, как надо понимать, id ), а не по каким-то полям
для поиска.
Всегда смотри в план запроса!
Это конечно правильно.
Posted via RSDN NNTP Server 2.0
Здравствуйте, MasterZiv, Вы писали:
MZ>Sinclair пишет:
>> Ну естественно медленно! План запроса посмотри — ужаснешься. Потом
>> добавь индекс по (x1, x2, x3, id) и посмотри, как оно полетит.
MZ>Такой составной индекс вряд ли нужен.
поясняю для недоверчивых: использование этого индекса позволит
а) выполнить index seek для фильтра x1 is null and x2=@criteria
б) избавиться от сортировки результата по x3
в) избавиться от bookmark lookup для доступа к id.
MZ>И кластерный обычно в MSSQL делают по PK
Не понял, при чем тут кластерный индекс.

1.2.0 alpha rev. 655
Здравствуйте, MasterZiv, Вы писали:
MZ>Такой составной индекс вряд ли нужен.
MZ>И кластерный обычно в MSSQL делают по PK
MZ>(который тут, как надо понимать, id ), а не по каким-то полям
MZ>для поиска.
Не всегда ПК самый лучший кандидат на звание кластерного