Warum hat SQL Server plötzlich entscheiden, zu verwenden, wie eine schreckliche Ausführungsplan?

Hintergrund

Wir hatten vor kurzem ein Problem mit der Abfrage-Pläne für sql server auf eines unserer größeren Tabellen (um 175,000,000 Zeilen). Die Spalten-und index-Struktur der Tabelle hat sich nicht geändert, die für 5+ Jahre.

Die Tabelle und die Indizes sieht wie folgt aus:

create table responses (
    response_uuid uniqueidentifier not null,
    session_uuid uniqueidentifier not null,
    create_datetime datetime not null,
    create_user_uuid uniqueidentifier not null,
    update_datetime datetime not null,
    update_user_uuid uniqueidentifier not null,
    question_id int not null,
    response_data varchar(4096) null,
    question_type_id varchar(3) not null,
    question_length tinyint null,
    constraint pk_responses primary key clustered (response_uuid),
    constraint idx_responses__session_uuid__question_id unique nonclustered (session_uuid asc, question_id asc) with (fillfactor=80),
    constraint fk_responses_sessions__session_uuid foreign key(session_uuid) references dbo.sessions (session_uuid),
    constraint fk_responses_users__create_user_uuid foreign key(create_user_uuid) references dbo.users (user_uuid),
    constraint fk_responses_users__update_user_uuid foreign key(update_user_uuid) references dbo.users (user_uuid)
)

create nonclustered index idx_responses__session_uuid_fk on responses(session_uuid) with (fillfactor=80)

Die Abfrage, die war schlecht (~2,5 Minuten anstatt der normalen <1 Sekunde-Leistung) sieht wie folgt aus:

SELECT 
[Extent1].[response_uuid] AS [response_uuid], 
[Extent1].[session_uuid] AS [session_uuid], 
[Extent1].[create_datetime] AS [create_datetime], 
[Extent1].[create_user_uuid] AS [create_user_uuid], 
[Extent1].[update_datetime] AS [update_datetime], 
[Extent1].[update_user_uuid] AS [update_user_uuid], 
[Extent1].[question_id] AS [question_id], 
[Extent1].[response_data] AS [response_data], 
[Extent1].[question_type_id] AS [question_type_id], 
[Extent1].[question_length] AS [question_length]
FROM [dbo].[responses] AS [Extent1]
WHERE [Extent1].[session_uuid] = @f6_p__linq__0;

(Die Abfrage generiert wird, die von entity framework und ausgeführt, unter Verwendung von sp_executesql)

Den Ausführungsplan während die Armen performance-Periode sah so aus:

Warum hat SQL Server plötzlich entscheiden, zu verwenden, wie eine schreckliche Ausführungsplan?

Einige Hintergrundinformationen über die Daten - ausführen der Abfrage oben würde nie wieder mehr als 400 Zeilen. In anderen Worten, Filter auf session_uuid wirklich beschränkt sich die Ergebnismenge.

Einige Hintergrundinformationen über die geplante Instandhaltung - ein zeitgesteuerter Auftrag ausgeführt wird auf einer wöchentlichen basis, um die Datenbank neu erstellen Statistiken und rebuild Indizes der Tabelle. Der job läuft ein Skript, das wie folgt aussieht:

alter index all on responses rebuild with (fillfactor=80)

Die Lösung für das performance-problem wurde führen Sie den index neu erstellen-Skript (oben) auf dieser Tabelle.

Andere möglicherweise relevante Einzelheiten... Die Verteilung der Daten hat sich nicht geändert, seit der letzten index neu erstellen. Es gibt keine joins in der Abfrage. Wir sind ein SAAS-shop, wir haben bei 50 - 100 live-Produktion von Datenbanken mit genau dem gleichen schema, einige mit mehr Daten, einige mit weniger, alle mit den gleichen Abfragen ausführen, gegen Sie sich über ein paar sql-Server.

Frage:

Was passiert sein könnte, würde der sql-server starten, mit dieser schrecklichen Ausführungsplan in dieser bestimmten Datenbank?

Beachten Sie, das problem wurde gelöst, indem einfach Neuerstellen der Indizes auf der Tabelle.

Vielleicht eine bessere Frage ist "was sind die Umstände, unter denen der sql-server würde aufhören, ein index?"

Anderen Weg, es zu betrachten ist: "warum würde der optimizer keinen index, der umgebaut wurde, vor ein paar Tagen und dann starten Sie es wieder nach einem Notfall neu erstellen des index einmal bemerkten wir, dass die schlechte Abfrage-plan?"

Schreibe einen Kommentar