Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Como APPROX_COUNT_DISTINCT() funciona no SQL Server


APPROX_COUNT_DISTINCT() é uma das novas funções introduzidas no SQL Server 2019. Essa função retorna o número aproximado de valores não nulos exclusivos em um grupo.

Basicamente, você pode usá-lo para obter uma ideia aproximada do número de linhas não duplicadas em uma tabela grande ou conjunto de resultados. Funciona de forma semelhante ao COUNT_BIG() e COUNT() funções (ao usar o DISTINCT cláusula), mas retorna um número aproximado em vez de um número preciso.

APPROX_COUNT_DISTINCT() destina-se principalmente a cenários de big data. Ele foi projetado para acessar grandes conjuntos de dados com mais de um milhão de linhas e agregar uma coluna ou colunas com muitos valores distintos. Destina-se a cenários em que a capacidade de resposta é mais crítica do que a precisão absoluta.

A Microsoft afirma que a implementação da função garante uma taxa de erro de até 2% dentro de uma probabilidade de 97%.

No momento da escrita, APPROX_COUNT_DISTINCT() é um recurso de visualização pública. Foi introduzido no SQL Server 2019, que também está atualmente em status de visualização.

Observe que a Microsoft afirma que os recursos de visualização não se destinam ao uso em produção.


Sintaxe


A sintaxe fica assim:
APPROX_COUNT_DISTINCT ( expression ) 

A expressão pode ser de qualquer tipo, exceto imagem , sql_variant , ntext , ou texto .

Exemplo 1 – COUNT() vs APPROX_COUNT_DISTINCT


Aqui está um exemplo básico comparando COUNT() com 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                  |
+----------------+-------------------------+-------------------------+

Nesse caso, a contagem real e a contagem distinta real são as mesmas (isso significa apenas que não havia duplicatas no OrderLineId coluna).

No entanto, vemos que APPROX_COUNT_DISTINCT() retornou um valor diferente. Isso é esperado, pois retorna apenas uma aproximação.

Exemplo 2 – Um número menor


Neste exemplo, especifico uma coluna diferente ( Descrição ) 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                     |
+----------------+-------------------------+-------------------------+

Nesse caso, a contagem real e a contagem distinta real são diferentes. Isso ocorre porque a Descrição coluna contém muitos valores duplicados.

Podemos ver que APPROX_COUNT_DISTINCT() ainda retornou um valor diferente, mas está bem próximo.

Como mencionado, APPROX_COUNT_DISTINCT() destina-se principalmente a conjuntos de resultados maiores. Conjuntos de resultados menores, como os aqui, são executados rapidamente, independentemente de qual função eu uso.

Verifique o tipo de dados


APPROX_COUNT_DISTINCT() retorna seu resultado como um bigint , então, nesse sentido, é mais semelhante a COUNT_BIG() do que para COUNT() (que retorna um int ). Mas vamos confirmar que:
EXEC sp_describe_first_result_set N'SELECT APPROX_COUNT_DISTINCT(OrderLineId) FROM Sales.OrderLines', null, 0;

Resultado (usando saída 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 é grande . Isso nos diz que nossa consulta retorna seus resultados como um bigint tipo de dados, como esperado. O max_length e precisão os valores também são consistentes com o bigint tipo de dados.