sql >> Base de Datos >  >> RDS >> Sqlserver

Cómo funciona APPROX_COUNT_DISTINCT() en SQL Server

APPROX_COUNT_DISTINCT() es una de las nuevas funciones introducidas en SQL Server 2019. Esta función devuelve el número aproximado de valores únicos no nulos en un grupo.

Básicamente, puede usarlo para tener una idea aproximada de la cantidad de filas no duplicadas en una tabla grande o un conjunto de resultados. Funciona de forma similar a COUNT_BIG() y COUNT() funciones (cuando se usa DISTINCT cláusula), pero devuelve un número aproximado en lugar de un número preciso.

APPROX_COUNT_DISTINCT() está dirigido principalmente a escenarios de big data. Está diseñado para acceder a grandes conjuntos de datos con más de un millón de filas y la agregación de una columna o columnas que tienen muchos valores distintos. Está diseñado para escenarios donde la capacidad de respuesta es más crítica que la precisión absoluta.

Microsoft afirma que la implementación de la función garantiza una tasa de error de hasta el 2 % con una probabilidad del 97 %.

Al momento de escribir, APPROX_COUNT_DISTINCT() es una función de vista previa pública. Se introdujo en SQL Server 2019, que también se encuentra actualmente en estado de vista previa.

Tenga en cuenta que Microsoft afirma que las funciones de vista previa no están diseñadas para uso en producción.

Sintaxis

La sintaxis es así:

APPROX_COUNT_DISTINCT ( expression ) 

La expresión puede ser de cualquier tipo, excepto imagen , variante_sql , ntext o texto .

Ejemplo 1:COUNT() frente a APPROX_COUNT_DISTINCT

Aquí hay un ejemplo básico comparando 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;

Resultado:

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

En este caso, el conteo real y el conteo distinto real es el mismo (esto solo significa que no hubo duplicados en el OrderLineId columna).

Sin embargo, vemos que APPROX_COUNT_DISTINCT() devolvió un valor diferente. Esto es de esperar, ya que solo devuelve una aproximación.

Ejemplo 2:un número más pequeño

En este ejemplo, especifico una columna diferente ( Descripción ) para contar:

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

Resultado:

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

En este caso, el recuento real y el recuento distinto real son diferentes. Esto se debe a que la Descripción columna contiene muchos valores duplicados.

Podemos ver que APPROX_COUNT_DISTINCT() aún devolvió un valor diferente, pero está bastante cerca.

Como se mencionó, APPROX_COUNT_DISTINCT() está diseñado principalmente para conjuntos de resultados más grandes. Los conjuntos de resultados más pequeños como los que se muestran aquí se ejecutan rápidamente independientemente de la función que use.

Verifique el tipo de datos

APPROX_COUNT_DISTINCT() devuelve su resultado como bigint , por lo que en ese sentido es más similar a COUNT_BIG() de lo que es para COUNT() (que devuelve un int ). Pero confirmemos que:

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

Resultado (usando salida vertical):

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

Podemos ver que system_type_name es bigint . Esto nos dice que nuestra consulta devuelve sus resultados como bigint tipo de datos, como se esperaba. La longitud_máxima y precisión los valores también son consistentes con el bigint tipo de datos.