Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Funktionsweise von APPROX_COUNT_DISTINCT() in SQL Server

APPROX_COUNT_DISTINCT() ist eine der neuen Funktionen, die in SQL Server 2019 eingeführt wurden. Diese Funktion gibt die ungefähre Anzahl eindeutiger Nicht-Null-Werte in einer Gruppe zurück.

Grundsätzlich können Sie es verwenden, um eine ungefähre Vorstellung von der Anzahl nicht doppelter Zeilen in einer großen Tabelle oder Ergebnismenge zu erhalten. Es funktioniert ähnlich wie COUNT_BIG() und COUNT() Funktionen (bei Verwendung der DISTINCT Klausel), aber es gibt eher eine ungefähre als eine genaue Zahl zurück.

APPROX_COUNT_DISTINCT() zielt hauptsächlich auf Big-Data-Szenarien ab. Es wurde für den Zugriff auf große Datensätze mit mehr als einer Million Zeilen und die Aggregation einer oder mehrerer Spalten mit vielen unterschiedlichen Werten entwickelt. Es ist für Szenarien gedacht, in denen Reaktionsfähigkeit wichtiger ist als absolute Präzision.

Microsoft gibt an, dass die Funktionsimplementierung eine Fehlerquote von bis zu 2 % bei einer Wahrscheinlichkeit von 97 % garantiert.

Zum Zeitpunkt des Schreibens APPROX_COUNT_DISTINCT() ist eine öffentliche Vorschaufunktion. Es wurde in SQL Server 2019 eingeführt, der sich derzeit ebenfalls im Vorschaustatus befindet.

Beachten Sie, dass Microsoft angibt, dass Vorschaufunktionen nicht für Produktionszwecke vorgesehen sind.

Syntax

Die Syntax lautet wie folgt:

APPROX_COUNT_DISTINCT ( expression ) 

Der Ausdruck kann von jedem Typ sein, außer image , sql_variante , ntext , oder Text .

Beispiel 1 – COUNT() vs. APPROX_COUNT_DISTINCT

Hier ist ein einfaches Beispiel zum Vergleich von COUNT() mit APPROX_COUNT_DISTINCT() :

USE WideWorldImporters;
SELECT 
  COUNT(OrderLineId) 'Actual Count',
  COUNT(DISTINCT OrderLineId) 'Actual Distinct Count',
  APPROX_COUNT_DISTINCT(OrderLineId) 'Approx Distinct Count'
FROM Sales.OrderLines;

Ergebnis:

+----------------+-------------------------+-------------------------+
| Actual Count   | Actual Distinct Count   | Approx Distinct Count   |
|----------------+-------------------------+-------------------------|
| 231412         | 231412                  | 238493                  |
+----------------+-------------------------+-------------------------+

In diesem Fall ist die tatsächliche Anzahl und die tatsächliche eindeutige Anzahl gleich (das bedeutet nur, dass es keine Duplikate in der OrderLineId gab Spalte).

Wir sehen jedoch, dass APPROX_COUNT_DISTINCT() einen anderen Wert zurückgegeben. Dies ist zu erwarten, da es nur eine Annäherung zurückgibt.

Beispiel 2 – Eine kleinere Zahl

In diesem Beispiel gebe ich eine andere Spalte an ( Description ) zu zählen:

SELECT 
  COUNT(Description) 'Actual Count',
  COUNT(DISTINCT Description) 'Actual Distinct Count',
  APPROX_COUNT_DISTINCT(Description) 'Approx Distinct Count'
FROM Sales.OrderLines;

Ergebnis:

+----------------+-------------------------+-------------------------+
| Actual Count   | Actual Distinct Count   | Approx Distinct Count   |
|----------------+-------------------------+-------------------------|
| 231412         | 227                     | 226                     |
+----------------+-------------------------+-------------------------+

In diesem Fall sind die tatsächliche Anzahl und die tatsächliche eindeutige Anzahl unterschiedlich. Das liegt daran, dass die Beschreibung Spalte enthält viele doppelte Werte.

Wir können sehen, dass APPROX_COUNT_DISTINCT() immer noch einen anderen Wert zurückgegeben, aber es ist ziemlich nah dran.

Wie bereits erwähnt, APPROX_COUNT_DISTINCT() ist hauptsächlich für größere Ergebnismengen gedacht. Kleinere Ergebnismengen wie die hier ausgeführten laufen schnell, unabhängig davon, welche Funktion ich verwende.

Überprüfen Sie den Datentyp

APPROX_COUNT_DISTINCT() gibt sein Ergebnis als bigint zurück , in dieser Hinsicht ist es also ähnlicher zu COUNT_BIG() als zu COUNT() (was ein int zurückgibt ). Aber lassen Sie uns das bestätigen:

EXEC sp_describe_first_result_set N'SELECT APPROX_COUNT_DISTINCT(OrderLineId) FROM Sales.OrderLines', null, 0;

Ergebnis (bei vertikaler Ausgabe):

is_hidden                    | 0
column_ordinal               | 1
name                         | NULL
is_nullable                  | 1
system_type_id               | 127
system_type_name             | bigint
max_length                   | 8
precision                    | 19
scale                        | 0
collation_name               | NULL
user_type_id                 | NULL
user_type_database           | NULL
user_type_schema             | NULL
user_type_name               | NULL
assembly_qualified_type_name | NULL
xml_collection_id            | NULL
xml_collection_database      | NULL
xml_collection_schema        | NULL
xml_collection_name          | NULL
is_xml_document              | 0
is_case_sensitive            | 0
is_fixed_length_clr_type     | 0
source_server                | NULL
source_database              | NULL
source_schema                | NULL
source_table                 | NULL
source_column                | NULL
is_identity_column           | 0
is_part_of_unique_key        | NULL
is_updateable                | 0
is_computed_column           | 0
is_sparse_column_set         | 0
ordinal_in_order_by_list     | NULL
order_by_is_descending       | NULL
order_by_list_length         | NULL
tds_type_id                  | 38
tds_length                   | 8
tds_collation_id             | NULL
tds_collation_sort_id        | NULL

Wir können diesen system_type_name sehen ist bigint . Dies sagt uns, dass unsere Abfrage ihre Ergebnisse als bigint zurückgibt Datentyp, wie erwartet. Die max_length und Präzision Werte stimmen auch mit dem bigint überein Datentyp.