Ich optimiere einige Indizes und sehe einige Probleme, die Ihren Rat annehmen möchten
Auf 1 Tabelle befinden sich 3 Indizes
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- Brauche ich wirklich die ersten 2 Indizes oder sollte ich sie löschen?
2- Es werden Abfragen ausgeführt, die eine Bedingung mit profileid = xxxx und eine andere Verwendungsbedingung mit profileid = xxxx und InstanceID = xxxxxx verwenden. Warum wählt der Optimierer den 3. Index, nicht den 1. oder 2.?
Außerdem führe ich eine Abfrage aus, bei der die Sperre für jeden Index wartet. Was soll ich tun, um diesen Index zu optimieren, wenn ich diese Zählungen erhalte?
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.
Tabellenstruktur ist
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
)
Dies ist ein Beispiel (diese Abfrage, die vom Ruhezustand erstellt wurde, sieht also seltsam aus)
(@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
sql-server
index
index-tuning
sebeid
quelle
quelle
Antworten:
Antwort auf Frage 1:
Nach dem, was Sie veröffentlicht haben, können Sie die ersten beiden Indizes löschen, da der dritte alle von Ihnen erwähnten Abfragen abdeckt und das Abfrageoptimierungsprogramm dies auch beim Erstellen des Abfrageplans sieht (basierend auf dem von Ihnen veröffentlichten Plan).
Antwort auf Frage 2:
Es wird immer der dritte Index verwendet, da der Index mit den zwei zusätzlichen Indexschlüsseln (
InstanceId and AddressType
) bereits mehr Daten enthält . Dies verhindert, dass SQL InstanceId und AddressType vom Primärschlüssel (dem Schlüssel-Lookup-Teil des Ausführungsplans) abrufen muss, um die Abfrage zu erfüllen.Ich würde vorschlagen, die ersten beiden Indizes zu löschen und den dritten mit Include-Spalten neu zu erstellen, um die anderen Spalten abzudecken, die in der Abfrage angefordert werden
Dies sollte bei den Abfragen helfen und die Schlüsselsuche aus dem Abfrageplan entfernen.
Sehen Sie, ob die Schlösser nach diesen Änderungen abfallen und wenn nicht, können wir etwas tiefer graben.
quelle
Nicht die angegebene Frage, aber möglicherweise bessere Abfragepläne mit besseren Abfragen.
Sie beenden das linke Äußere mit dem
Punkt, an dem profiledmo1_.Id=@P0 dies in einen Join umwandelt
Auf Indizes nur die ersten beiden
Alles, was der Join tut, ist sicherzustellen, dass er sich im Profil befindet, aber Sie melden nichts vom Profil
und wie ist das nicht?
quelle
Es scheint, als könnten Sie Index 1 und 2 löschen, da Index 3 alle Informationen (Spalten) enthält, die Sie benötigen. Möglicherweise ist ein anderer Index als Clustered-Index zur Darstellung des Primärschlüssels sinnvoll.
Mit diesen begrenzten Informationen können wir nur raten. Wenn Sie weitere Hinweise benötigen, veröffentlichen Sie bitte detailliertere Informationen wie Ihre vollständige Tabellenstruktur (Tabellen, Index, Schlüssel, ...), Ihre Abfragen und den Ausführungsplan.
quelle