Domanda di ottimizzazione dell'indice


8

Sto sintonizzando alcuni indici e vedendo alcuni problemi vorrei ricevere il tuo consiglio

Su 1 tabella ci sono 3 indici

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- Ho davvero bisogno dei primi 2 indici o dovrei lasciarli cadere?

2- sono in esecuzione query che utilizzano la condizione in cui profileid = xxxx e altre condizioni d'uso in cui profileid = xxxx e InstanceID = xxxxxx. Perché l'ottimizzatore sceglie il 3o indice non il 1o o 2o?

Inoltre sto eseguendo una query che ottiene l'attesa di blocco su ciascun indice. Se ricevo questi conteggi, cosa devo fare per ottimizzare questo indice?

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.

la struttura della tabella è

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
 )

questo è un esempio (questa query creata da Hibernate sembra così strana)

(@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 

inserisci qui la descrizione dell'immagine

(@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

inserisci qui la descrizione dell'immagine


Qualunque possibilità tu possa aggiungere in quale sia la struttura della tabella completa, qual è la chiave di clustering e quindi quali altre colonne vengono incluse nelle query che cercano profileid = xxxx e la query con profilerid = xxxx e instanceid = xxxx. C'è un sacco di "dipende" in queste risposte e avere tali informazioni aiuterebbe sicuramente a spiegare da cosa dipende.
mskinner,

Maggiori informazioni sui dati sarebbero utili. Ad esempio, se le statistiche sono state aggiornate nella tabella, quanti record ci sono nella tabella insieme all'unicità e così via.
Glen Swan,

@GlenSwan, ci sono 567644 record in questa tabella. Le statistiche sono state aggiornate due volte a settimana. Martedì e sabato
sebe

2
Si prega di fare le proprie ricerche sul confronto delle funzionalità. Sebbene vi siano alcune sovrapposizioni, i cluster di failover e i gruppi di disponibilità hanno funzionalità diverse e soddisfano requisiti diversi, quindi non si può davvero chiedere genericamente quale sia la migliore. Devi confrontare le caratteristiche di ciascuno con le tue reali esigenze aziendali. Inoltre, qui le domande su licenze / costi non sono in argomento. Si prega di leggere questo meta post per intero .
Aaron Bertrand

Risposte:


6

Risposta alla domanda 1:

Da ciò che hai pubblicato puoi eliminare i primi due indici poiché il terzo coprirà tutte le query menzionate e lo Strumento per ottimizzare le query vede che anche quando crea il piano di query (in base al piano che hai pubblicato).

Risposta alla domanda 2:

Utilizza sempre il terzo indice perché contiene già più dati nell'indice con le due chiavi di indice aggiuntive ( InstanceId and AddressType). Ciò impedisce a SQL di dover estrarre InstanceId e AddressType dalla chiave primaria (la parte di ricerca della chiave del piano di esecuzione) per soddisfare la query.

Quello che vorrei suggerire è di eliminare i primi due indici e ricostruire il terzo con le colonne include per coprire le altre colonne richieste nella query

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)

Ciò dovrebbe aiutare con le query e rimuovere la ricerca delle chiavi dal piano delle query.

Vedi se i blocchi cadono dopo queste modifiche e se non lo fanno possiamo scavare un po 'più a fondo.


ho fatto quello che mi consiglia e non c'è più la ricerca delle chiavi. sto monitorando i blocchi .. ho ancora bisogno di qualche chiarimento per questi conteggi Il blocco della riga attende: 484; durata totale: 59 minuti; durata media: 7 secondi; Blocco pagina in attesa: 5; durata totale: 11 secondi; durata media: 2 secondi; Tentativi di escalation di blocco: 36.949; Escalation effettive: 0.
sebeid

@sebeid quando vengono inseriti inserimenti / aggiornamenti / eliminazioni nella tabella degli indirizzi anche altre tabelle vengono modificate dalla stessa richiesta batch? In tal caso, il batch avvia esplicitamente una transazione per tutte le istruzioni di modifica in batch e si impegna o esegue il rollback solo alla fine del batch?
Aaron,

non lo so, da dove posso ottenere queste informazioni. Grazie
sebeid

2
@sebeid se tutto è una dichiarazione generata da ibernazione, chiederei ai tuoi sviluppatori in quanto potrebbe essere l'approccio più semplice, altrimenti dovrai tracciare o impostare un evento esteso per provare a intercettare le chiamate in modo da poter vedere cosa sta succedendo l'istruzione batch. Esempio di profiler per eventi estesi
Aaron,

3

Non è la domanda dichiarata ma potresti ottenere piani di query migliori con query migliori
Stai uccidendo l'esterno sinistro con il punto in
cui profiledmo1_.Id=@P0 lo trasforma in un join

Sugli indici solo i primi due

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

tutto ciò che fa join è assicurarsi che sia nel profilo, ma non stai segnalando nulla dal profilo
e come mai no?

select addressdmo0_.Id as Id1_20_
     , ...
     , addressdmo0_.Zip as Zip14_20_ 
  from dbo.Address addressdmo0_ 
 where addressdmo0_.ProfileId  = @P0 
   and addressdmo0_.InstanceId = @P1

2

Sembra che potresti eliminare l'indice 1 e 2 poiché l'indice 3 include tutte le informazioni (colonne) necessarie. Potrebbe essere possibile che un altro indice abbia senso come indice cluster per rappresentare la chiave primaria.

Con queste informazioni limitate possiamo solo indovinare. Se hai bisogno di ulteriori suggerimenti, inserisci informazioni più dettagliate come la struttura completa della tabella (tabelle, indice, chiavi, ...), le tue query e il piano di esecuzione.


1
O un indice cluster che non rappresenta la chiave primaria. Sebbene queste due cose siano spesso strettamente associate tra loro e mentre una chiave primaria viene creata come cluster per impostazione predefinita, non sono (e non devono essere) la stessa cosa.
Aaron Bertrand

Questo è vero ovviamente. :-)
Josh Alvo
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.