sql >> Databasteknik >  >> RDS >> Sqlserver

Hur APPROX_COUNT_DISTINCT() fungerar i SQL Server

APPROX_COUNT_DISTINCT() är en av de nya funktionerna som introduceras i SQL Server 2019. Denna funktion returnerar det ungefärliga antalet unika icke-nullvärden i en grupp.

I grund och botten kan du använda den för att få en ungefärlig uppfattning om antalet icke-duplicerade rader i en stor tabell eller resultatuppsättning. Det fungerar på samma sätt som COUNT_BIG() och COUNT() funktioner (när du använder DISTINCT sats), men den returnerar ett ungefärligt tal snarare än ett exakt tal.

APPROX_COUNT_DISTINCT() är främst inriktad på big data-scenarier. Den är utformad för att komma åt stora datamängder med mer än en miljon rader och aggregering av en kolumn eller kolumner som har många distinkta värden. Den är avsedd för scenarier där lyhördhet är viktigare än absolut precision.

Microsoft uppger att funktionsimplementeringen garanterar en felfrekvens på upp till 2 % med en sannolikhet på 97 %.

I skrivande stund, APPROX_COUNT_DISTINCT() är en offentlig förhandsvisningsfunktion. Det introducerades i SQL Server 2019, som också för närvarande är i förhandsvisningsstatus.

Observera att Microsoft anger att förhandsgranskningsfunktioner inte är avsedda för produktionsanvändning.

Syntax

Syntaxen ser ut så här:

APPROX_COUNT_DISTINCT ( uttryck ) 

Uttrycket kan vara av vilken typ som helst, förutom bild , sql_variant , ntext , eller text .

Exempel 1 – COUNT() kontra APPROX_COUNT_DISTINCT

Här är ett grundläggande exempel som jämför COUNT() med APPROX_COUNT_DISTINCT() :

ANVÄND WideWorldImporters;SELECT COUNT(OrderLineId) 'Factual Count', COUNT(DISTINCT OrderLineId) 'Factual Distinct Count', APPROX_COUNT_DISTINCT(OrderLineId) 'Crox Distinct Count'FROM Sales.OrderL 

Resultat:

+----------------+-------------------------+--- ----------------------------+| Faktiskt antal | Faktiskt distinkt antal | Ungefär distinkt antal ||----------------+--------------------------------+-- ----------------------------|| 231412 | 231412 | 238493 |+----------------+------------------------+---- ---------------------+

I det här fallet är det faktiska antalet och det faktiska distinkta antalet detsamma (detta betyder bara att det inte fanns några dubbletter i OrderLineId kolumn).

Vi ser dock att APPROX_COUNT_DISTINCT() returnerade ett annat värde. Detta är förväntat, eftersom det bara ger en uppskattning.

Exempel 2 – Ett mindre antal

I det här exemplet anger jag en annan kolumn ( Beskrivning ) för att räkna:

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

Resultat:

+----------------+-------------------------+--- ----------------------------+| Faktiskt antal | Faktiskt distinkt antal | Ungefär distinkt antal ||----------------+--------------------------------+-- ----------------------------|| 231412 | 227 | 226 |+----------------+------------------------+---- ---------------------+

I det här fallet är det faktiska antalet och det faktiska distinkta antalet olika. Detta beror på att Beskrivning kolumnen innehåller många dubbletter av värden.

Vi kan se att APPROX_COUNT_DISTINCT() returnerade fortfarande ett annat värde, men det är ganska nära.

Som nämnts, APPROX_COUNT_DISTINCT() är främst avsedd för större resultatuppsättningar. Mindre resultatuppsättningar som de här körs snabbt oavsett vilken funktion jag använder.

Kontrollera datatypen

APPROX_COUNT_DISTINCT() returnerar resultatet som en bigint , så i det avseendet liknar den mer COUNT_BIG() än det är till COUNT() (som returnerar en int ). Men låt oss bekräfta det:

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

Resultat (med vertikal utdata):

är_dold | 0column_ordinal | 1namn | NULLis_nullable | 1system_typ_id | 127systemtypnamn | bigintmax_length | 8precision | 19 skala | 0kollationsnamn | NULLuser_type_id | NULLuser_type_database | NULLuser_type_schema | NULLuser_type_name | NULLassembly_qualified_type_name | NULLxml_samlings-id | NULLxml_samlingsdatabas | NULLxml_samlingsschema | NULLxml_samlingsnamn | NULLis_xml_document | 0är_skiftlägeskänslig | 0is_fixed_length_clr_type | 0källa_server | NULLsource_databas | NULLsource_schema | NULLsource_table | NULLkälla_kolumn | NULLis_identity_column | 0is_part_of_unique_key | NULLis_updateable | 0is_computed_column | 0is_sparse_column_set | 0ordinal_in_order_by_list | NULLorder_efter_är_fallande | NULLorder_efter_lista_längd | NULLtds_type_id | 38tds_length | 8tds_collation_id | NULLtds_collation_sort_id | NULL

Vi kan se att system_type_name är stor . Detta talar om för oss att vår sökning returnerar sina resultat som en bigint datatyp, som förväntat. max_length och precision värden överensstämmer också med bigint datatyp.


  1. Är det dålig design att använda arrayer i en databas?

  2. Hur får man storleken på en MySQL-databas?

  3. SQL Server - transaktioner återgår vid fel?

  4. För- och nackdelar med att använda SqlCommand Prepare i C#?