Вопрос настройки индекса

8

Я настраиваю некоторые индексы и, видя некоторые проблемы, хотел бы воспользоваться вашим советом

На 1 таблицу 3 индекса

dbo.Address.IX_Address_ProfileId 
[1 KEY] ProfileId {int 4}
Reads: 0 Writes:10,519

dbo.Address.IX_Address 
[2 KEYS] ProfileId {int 4}, InstanceId {int 4}
Reads: 0 Writes:10,523

dbo.Address.IX_Address_profile_instance_addresstype
[3 KEYS] ProfileId {int 4}, InstanceId {int 4}, AddressType {int 4}
Reads: 149677 (53,247 seek) Writes:10,523

1- Мне действительно нужны первые 2 индекса или я должен их отбросить?

2 - выполняются запросы, использующие условие, где profileid = xxxx и другие условия использования, где profileid = xxxx и InstanceID = xxxxxx. Почему оптимизатор выбирает 3-й индекс, а не 1-й или 2-й?

Также я выполняю запрос, который получает ожидание блокировки для каждого индекса. Если я получаю эти цифры, что я должен сделать, чтобы настроить этот индекс?

Row lock waits: 484; total duration: 59 minutes; avg duration: 7 seconds; 
Page lock waits: 5; total duration: 11 seconds; avg duration: 2 seconds; 
Lock escalation attempts: 36,949; Actual Escalations: 0.

структура таблицы

TABLE [dbo].[Address](
[Id] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
[AddressType] [int] NULL,
[isPreferredAddress] [bit] NULL,
[StreetAddress1] [nvarchar](255) NULL,
[StreetAddress2] [nvarchar](255) NULL,
[City] [nvarchar](50) NULL,
[State_Id] [int] NOT NULL,
[Zip] [varchar](20) NULL,
[Country_Id] [int] NOT NULL,
[CurrentUntil] [date] NULL,
[CreatedDate] [datetime] NOT NULL,
[UpdatedDate] [datetime] NOT NULL,
[ProfileId] [int] NOT NULL,
[InstanceId] [int] NOT NULL,
[County_id] [int] NULL,
 CONSTRAINT [PK__Address__3214EC075E4BE276] PRIMARY KEY CLUSTERED 
(
   [Id] ASC
 )

это пример (этот запрос, созданный hibernate, выглядит странно)

(@P0 bigint)select addresses0_.ProfileId as Profile15_109_1_
, addresses0_.Id as Id1_20_1_
, addresses0_.Id as Id1_20_0_
, addresses0_.AddressType as AddressT2_20_0_
, addresses0_.City as City3_20_0_
, addresses0_.Country_Id as Country_4_20_0_
, addresses0_.County_id as County_i5_20_0_
, addresses0_.CreatedDate as CreatedD6_20_0_
, addresses0_.CurrentUntil as CurrentU7_20_0_
, addresses0_.InstanceId as Instance8_20_0_
, addresses0_.isPreferredAddress as isPrefer9_20_0_
, addresses0_.ProfileId as Profile15_20_0_
, addresses0_.State_Id as State_I10_20_0_
, addresses0_.StreetAddress1 as StreetA11_20_0_
, addresses0_.StreetAddress2 as StreetA12_20_0_
, addresses0_.UpdatedDate as Updated13_20_0_
, addresses0_.Zip as Zip14_20_0_ 
from dbo.Address addresses0_ 
where addresses0_.ProfileId=@P0 

введите описание изображения здесь

(@P0 bigint,@P1 bigint)
select addressdmo0_.Id as Id1_20_
, addressdmo0_.AddressType as AddressT2_20_
, addressdmo0_.City as City3_20_
, addressdmo0_.Country_Id as Country_4_20_
, addressdmo0_.County_id as County_i5_20_
, addressdmo0_.CreatedDate as CreatedD6_20_
, addressdmo0_.CurrentUntil as CurrentU7_20_
, addressdmo0_.InstanceId as Instance8_20_
, addressdmo0_.isPreferredAddress as isPrefer9_20_
, addressdmo0_.ProfileId as Profile15_20_
, addressdmo0_.State_Id as State_I10_20_
, addressdmo0_.StreetAddress1 as StreetA11_20_
, addressdmo0_.StreetAddress2 as StreetA12_20_
, addressdmo0_.UpdatedDate as Updated13_20_
, addressdmo0_.Zip as Zip14_20_ 
from dbo.Address addressdmo0_ 
left outer join dbo.Profile profiledmo1_ 
on addressdmo0_.ProfileId=profiledmo1_.Id 
where profiledmo1_.Id=@P0 and addressdmo0_.InstanceId=@P1

введите описание изображения здесь

sebeid
источник
Любой шанс добавить в структуру полной таблицы, что такое ключ кластеризации и какие столбцы включены в запросы, которые ищут profileid = xxxx и запрос с profilerid = xxxx и instanceid = xxxx. В этих ответах есть много «это зависит», и наличие этой информации определенно поможет объяснить, от чего она зависит.
mskinner
Было бы полезно больше информации о данных. Например, если статистика была обновлена ​​в таблице, сколько записей в таблице вместе с уникальностью и так далее.
Глен Свон
@GlenSwan, в этой таблице 567644 записей. Статистика обновляется два раза в неделю. Вторник и субботу
sebeid
2
Пожалуйста, сделайте свое собственное исследование о сравнении характеристик. Несмотря на то, что есть некоторые совпадения, отказоустойчивые кластеры и группы доступности имеют разные функции и отвечают разным требованиям, поэтому вы не можете в общем спросить, какая из них лучше. Вам необходимо сравнить характеристики каждого из них с вашими фактическими потребностями бизнеса. Кроме того, вопросы лицензирования / стоимости здесь не обсуждаются. Пожалуйста, прочитайте этот мета пост полностью .
Аарон Бертран

Ответы:

6

Ответ на вопрос 1:

Из того, что вы опубликовали, вы можете удалить первые два индекса, так как третий будет охватывать все упомянутые вами запросы, и оптимизатор запросов также увидит это при создании плана запроса (на основе опубликованного вами плана).

Ответ на вопрос 2:

Он всегда использует третий индекс, потому что в нем уже есть больше данных с двумя дополнительными индексными ключами ( InstanceId and AddressType). Это избавляет SQL от необходимости извлекать InstanceId и AddressType из первичного ключа (часть поиска ключа плана выполнения) для удовлетворения запроса.

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

Create index IX_Address_profile_instance_addresstype 
on dbo.address  (ProfileId, InstanceId, AddressType) 
include(<put in the remaining columns comma delimited>) 
with (drop_existing=on,sort_in_tempdb=on)

Это должно помочь с запросами и должно удалить поиск ключа из плана запроса.

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

Аарон
источник
Я сделал то, что вы рекомендуете, и больше нет поиска ключей. Я наблюдаю за блокировками. Мне все еще нужны некоторые пояснения по этим подсчетам Ожидания блокировки строк: 484; общая продолжительность: 59 минут; средняя продолжительность: 7 секунд; Ожидание блокировки страницы: 5; общая продолжительность: 11 секунд; средняя продолжительность: 2 секунды; Попытки эскалации блокировки: 36 949; Фактические Эскалации: 0.
Sebeid
@sebeid, когда вставки / обновления / удаления выполняются в таблице адресов, другие таблицы также модифицируются тем же пакетным запросом? Если да, то запускает ли пакет явно транзакцию для всех операторов модификации в пакете и выполняет только фиксацию или откат в конце пакета?
Аарон
я не знаю, откуда я могу получить эту информацию. Спасибо
Себейд
2
@sebeid если все это сгенерированное утверждение из hibernate, я бы попросил ваших разработчиков, так как это может быть самым простым подходом, в противном случае вам нужно будет отслеживать или настраивать расширенное событие, чтобы попытаться перехватить вызовы, чтобы вы могли видеть, что все встречается в Пакетная выписка. Пример профилировщика расширенных событий
Aaron
3

Не заданный вопрос, но может получить лучшие планы запросов с лучшими запросами.
Вы убиваете левое внешнее с помощью где,
где profiledmo1_.Id=@P0 превращает это в соединение

По индексам только первые два

select addressdmo0_.Id as Id1_20_
     , ...
     , addressdmo0_.Zip as Zip14_20_ 
  from dbo.Address addressdmo0_ 
  join dbo.Profile profiledmo1_ 
    on addressdmo0_.ProfileId = profiledmo1_.Id 
   and profiledmo1_.Id = @P0 
   and addressdmo0_.InstanceId = @P1

все, что делает присоединение, - это убедитесь, что оно есть в профиле, но вы ничего не сообщаете из профиля,
и как это не так?

select addressdmo0_.Id as Id1_20_
     , ...
     , addressdmo0_.Zip as Zip14_20_ 
  from dbo.Address addressdmo0_ 
 where addressdmo0_.ProfileId  = @P0 
   and addressdmo0_.InstanceId = @P1
папараццо
источник
2

Кажется, что вы могли бы отбросить индексы 1 и 2, так как индекс 3 включает всю необходимую информацию (столбцы). Вполне возможно, что другой индекс имеет смысл как кластерный индекс для представления первичного ключа.

С этой ограниченной информацией мы можем только догадываться. Если вам нужны дополнительные подсказки, пожалуйста, опубликуйте более подробную информацию в виде полной структуры таблицы (таблицы, индекс, ключи и т. Д.), Ваших запросов и плана выполнения.

Джош Алво
источник
1
Или кластерный индекс, который не представляет первичный ключ. Хотя эти две вещи часто тесно связаны друг с другом, и хотя первичный ключ создается как кластеризованный по умолчанию, они не являются (и не должны быть) одинаковыми.
Аарон Бертран
Это правда, конечно. :-)
Джош Алво