In meiner Anwendung muss ich Tabellen mit Millionen von Zeilen verbinden. Ich habe eine Frage wie diese:
SELECT DISTINCT "f"."id" AS "FileId"
, "f"."name" AS "FileName"
, "f"."year" AS "FileYear"
, "vt"."value" AS "value"
FROM files "f"
JOIN "clients" "cl" ON("f"."cid" = "cl"."id" AND "cl"."id" = 10)
LEFT JOIN "value_text" "vt" ON ("f"."id" = "vt"."id_file" AND "vt"."id_field" = 65739)
GROUP BY "f"."id", "f"."name", "f"."year", "vt"."value"
Die Tabelle "files" hat 10 Millionen Zeilen und die Tabelle "value_text" hat 40 Millionen Zeilen.
Diese Abfrage ist zu langsam. Die Ausführung dauert zwischen 40 Sekunden (15000 Ergebnisse) und 3 Minuten (65000 Ergebnisse).
Ich hatte darüber nachgedacht, die beiden Abfragen zu teilen, kann es aber nicht, weil ich manchmal nach der verbundenen Spalte (Wert) bestellen muss ...
Was kann ich machen? Ich verwende SQL Server mit Azure. Insbesondere Azure SQL-Datenbank mit Preis- / Modellstufe "PRS1 PremiumRS (125 DTUs)" .
Ich erhalte viele Daten, aber ich denke, die Internetverbindung ist kein Engpass, da ich bei anderen Abfragen auch viele Daten erhalte und diese schneller sind.
Ich habe versucht, die Client-Tabelle als Unterabfrage zu verwenden und DISTINCT
mit den gleichen Ergebnissen zu entfernen .
Ich habe 1428 Zeilen in der Client-Tabelle.
zusätzliche Information
clients
Tabelle:
CREATE TABLE [dbo].[clients](
[id] [bigint] IDENTITY(1,1) NOT NULL,
[code] [nvarchar](70) NOT NULL,
[password] [nchar](40) NOT NULL,
[name] [nvarchar](150) NOT NULL DEFAULT (N''),
[email] [nvarchar](255) NULL DEFAULT (NULL),
[entity] [int] NOT NULL DEFAULT ((0)),
[users] [int] NOT NULL DEFAULT ((0)),
[status] [varchar](8) NOT NULL DEFAULT ('inactive'),
[created] [datetime2](7) NULL DEFAULT (getdate()),
[activated] [datetime2](7) NULL DEFAULT (getdate()),
[client_type] [varchar](10) NOT NULL DEFAULT ('normal'),
[current_size] [bigint] NOT NULL DEFAULT ((0)),
CONSTRAINT [PK_clients_id] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON),
CONSTRAINT [clients$code] UNIQUE NONCLUSTERED
(
[code] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)
files
Tabelle:
CREATE TABLE [dbo].[files](
[id] [bigint] IDENTITY(1,1) NOT NULL,
[cid] [bigint] NOT NULL DEFAULT ((0)),
[eid] [bigint] NOT NULL DEFAULT ((0)),
[year] [bigint] NOT NULL DEFAULT ((0)),
[name] [nvarchar](255) NOT NULL DEFAULT (N''),
[extension] [int] NOT NULL DEFAULT ((0)),
[size] [bigint] NOT NULL DEFAULT ((0)),
[id_doc] [bigint] NOT NULL DEFAULT ((0)),
[created] [datetime2](7) NULL DEFAULT (getdate())
CONSTRAINT [PK_files_id] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON),
CONSTRAINT [files$estructure_unique] UNIQUE NONCLUSTERED
(
[year] ASC,
[name] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)
GO
ALTER TABLE [dbo].[files] WITH NOCHECK ADD CONSTRAINT [FK_files_client] FOREIGN KEY([cid])
REFERENCES [dbo].[clients] ([id])
ON UPDATE CASCADE
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[files] CHECK CONSTRAINT [FK_files_client]
GO
value_text
Tabelle:
CREATE TABLE [dbo].[value_text](
[id] [bigint] IDENTITY(1,1) NOT NULL,
[id_file] [bigint] NOT NULL DEFAULT ((0)),
[id_field] [bigint] NOT NULL DEFAULT ((0)),
[value] [nvarchar](255) NULL DEFAULT (NULL),
[id_doc] [bigint] NULL DEFAULT (NULL)
CONSTRAINT [PK_value_text_id] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)
GO
ALTER TABLE [dbo].[value_text] WITH NOCHECK ADD CONSTRAINT [FK_valuesT_field] FOREIGN KEY([id_field])
REFERENCES [dbo].[fields] ([id])
ON UPDATE CASCADE
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[value_text] CHECK CONSTRAINT [FK_valuesT_field]
GO
Ausführungsplan:
* Ich habe die Tabellen und Felder in dieser Frage zum allgemeinen Verständnis übersetzt. In diesem Bild entspricht "archivos" "files", "clientes" von "clients" und "valores_texto" von "value_text".
Ausführungsplan ohne DISTINCT
:
Ausführungsplan ohne DISTINCT
und GROUP BY
(etwas schneller abfragen):
Abfragetest (Antwort von Krismorte)
Dies ist der Ausführungsplan der Abfrage, der langsamer als zuvor ist. Hier gibt mir die Abfrage über 400.000 Zeilen zurück, aber selbst wenn die Ergebnisse paginiert werden, gibt es keine Änderungen.
Ausführungsplan detaillierter: https://www.brentozar.com/pastetheplan/?id=By_UC2aBG
Und dies ist der Ausführungsplan der Abfrage, der schneller als zuvor ist. Hier gibt die Abfrage über 65.000 Zeilen zurück.
Ausführungsplan detaillierter: https://www.brentozar.com/pastetheplan/?id=r116e6pSM