Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Come funziona APPROX_COUNT_DISTINCT() in SQL Server

APPROX_COUNT_DISTINCT() è una delle nuove funzioni introdotte in SQL Server 2019. Questa funzione restituisce il numero approssimativo di valori univoci non null in un gruppo.

Fondamentalmente, puoi usarlo per avere un'idea approssimativa del numero di righe non duplicate in una tabella di grandi dimensioni o in un set di risultati. Funziona in modo simile a COUNT_BIG() e COUNT() funzioni (quando si utilizza il DISTINCT clausola), ma restituisce un numero approssimativo anziché un numero preciso.

APPROX_COUNT_DISTINCT() si rivolge principalmente a scenari di big data. È progettato per l'accesso a set di dati di grandi dimensioni con più di un milione di righe e per l'aggregazione di una o più colonne con molti valori distinti. È destinato a scenari in cui la reattività è più critica della precisione assoluta.

Microsoft afferma che l'implementazione della funzione garantisce un tasso di errore fino al 2% con una probabilità del 97%.

Al momento della scrittura, APPROX_COUNT_DISTINCT() è una funzione di anteprima pubblica. È stato introdotto in SQL Server 2019, anch'esso attualmente in stato di anteprima.

Tieni presente che Microsoft afferma che le funzionalità di anteprima non sono destinate all'uso in produzione.

Sintassi

La sintassi è questa:

APPROX_COUNT_DISTINCT ( expression ) 

L'espressione può essere di qualsiasi tipo, eccetto immagine , variante_sql , ntesto o testo .

Esempio 1 – COUNT() vs APPROX_COUNT_DISTINCT

Ecco un esempio di base che confronta COUNT() con 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;

Risultato:

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

In questo caso, il conteggio effettivo e il conteggio distinto effettivo sono gli stessi (questo significa solo che non c'erano duplicati in OrderLineId colonna).

Tuttavia, vediamo che APPROX_COUNT_DISTINCT() restituito un valore diverso. Questo è prevedibile, poiché restituisce solo un'approssimazione.

Esempio 2:un numero più piccolo

In questo esempio, specifico una colonna diversa ( Descrizione ) contare:

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

Risultato:

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

In questo caso, il conteggio effettivo e il conteggio distinto effettivo sono diversi. Questo perché la Descrizione la colonna contiene molti valori duplicati.

Possiamo vedere che APPROX_COUNT_DISTINCT() ha ancora restituito un valore diverso, ma è abbastanza vicino.

Come accennato, APPROX_COUNT_DISTINCT() è destinato principalmente a set di risultati più grandi. I set di risultati più piccoli come quelli qui vengono eseguiti rapidamente indipendentemente dalla funzione che utilizzo.

Controlla il tipo di dati

APPROX_COUNT_DISTINCT() restituisce il risultato come bigint , quindi a questo proposito è più simile a COUNT_BIG() rispetto a COUNT() (che restituisce un int ). Ma confermiamo che:

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

Risultato (usando l'output verticale):

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

Possiamo vedere che system_type_name è bigint . Questo ci dice che la nostra query restituisce i risultati come bigint tipo di dati, come previsto. La lunghezza_max e precisione i valori sono coerenti anche con il bigint tipo di dati.