sql >> Database >  >> RDS >> Sqlserver

Hoe APPROX_COUNT_DISTINCT() werkt in SQL Server

APPROX_COUNT_DISTINCT() is een van de nieuwe functies die zijn geïntroduceerd in SQL Server 2019. Deze functie retourneert het geschatte aantal unieke niet-null-waarden in een groep.

In principe kunt u het gebruiken om bij benadering een idee te krijgen van het aantal niet-dubbele rijen in een grote tabel of resultatenset. Het werkt vergelijkbaar met de COUNT_BIG() en COUNT() functies (bij gebruik van de DISTINCT clausule), maar het geeft een getal bij benadering terug in plaats van een precies getal.

APPROX_COUNT_DISTINCT() is vooral gericht op big data scenario's. Het is ontworpen voor toegang tot grote datasets met meer dan een miljoen rijen en aggregatie van een kolom of kolommen met veel verschillende waarden. Het is bedoeld voor scenario's waarin reactievermogen belangrijker is dan absolute precisie.

Microsoft stelt dat de functie-implementatie een foutenpercentage van maximaal 2% garandeert binnen een waarschijnlijkheid van 97%.

Op het moment van schrijven, APPROX_COUNT_DISTINCT() is een openbare preview-functie. Het werd geïntroduceerd in SQL Server 2019, dat momenteel ook in de preview-status is.

Merk op dat Microsoft stelt dat preview-functies niet bedoeld zijn voor productiegebruik.

Syntaxis

De syntaxis gaat als volgt:

APPROX_COUNT_DISTINCT ( expression ) 

De uitdrukking kan van elk type zijn, behalve afbeelding , sql_variant , ntekst , of tekst .

Voorbeeld 1 – COUNT() versus APPROX_COUNT_DISTINCT

Hier is een eenvoudig voorbeeld waarin COUNT() . wordt vergeleken met 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;

Resultaat:

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

In dit geval zijn de werkelijke telling en de werkelijke afzonderlijke telling hetzelfde (dit betekent alleen dat er geen duplicaten waren in de OrderLineId kolom).

We zien echter dat APPROX_COUNT_DISTINCT() een andere waarde geretourneerd. Dit is te verwachten, omdat het slechts een benadering oplevert.

Voorbeeld 2 – Een kleiner getal

In dit voorbeeld geef ik een andere kolom op ( Beschrijving ) om te tellen:

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

Resultaat:

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

In dit geval zijn de werkelijke telling en de werkelijke afzonderlijke telling verschillend. Dit komt omdat de Beschrijving kolom bevat veel dubbele waarden.

We kunnen zien dat APPROX_COUNT_DISTINCT() heeft nog steeds een andere waarde geretourneerd, maar het komt redelijk in de buurt.

Zoals vermeld, APPROX_COUNT_DISTINCT() is vooral bedoeld voor grotere resultaatsets. Kleinere resultaatsets zoals die hier werken snel, ongeacht welke functie ik gebruik.

Controleer het gegevenstype

APPROX_COUNT_DISTINCT() geeft het resultaat terug als een bigint , dus in dat opzicht lijkt het meer op COUNT_BIG() dan het is om COUNT() (die een int . retourneert ). Maar laten we dat bevestigen:

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

Resultaat (met verticale uitvoer):

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

We kunnen zien dat system_type_name is groot . Dit vertelt ons dat onze zoekopdracht de resultaten retourneert als een bigint gegevenstype, zoals verwacht. De max_length en precisie waarden komen ook overeen met de groten gegevenstype.


  1. Oplossen Index voor tabelgebruiker is beschadigd; probeer het te repareren

  2. Een SQL Plus-script uitvoeren in PowerShell

  3. Voorbeeld van het verbeteren van queryprestaties met indexen

  4. Oplossingen voor SQL Server 2012 &2014 Online Index Rebuild Probleem