APPROX_COUNT_DISTINCT

Herkese Selam,

Bu yazıda sizlere Oracle 12c 12.1.0.2 sürümü ile gelen  APPROX_COUNT_DISTINCT komutundan bahsedeceğim umarım farkındalık anlamında faydalı bir yazı olur.

Gerek yaptığımız rutin data testlerinde, gerekse veri analiz ederken COUNT(DISTINCT …) komutunu bir hayli kullanırız. Bu komutun çalışma süresi verimizin büyüklüğüne göre bazen bir hayli zaman alabilmekte. Bunun temel nedenin distinct komutunun arka planda bir sort operasyonunun yapılmasına neden olmasıdır. Sort işlemi bilindiği üzere DB seviyesinde verinin boyutuna göre en uzun sürebilecek temel operasyonlardan biridir. Oracle COUNT(DISTINCT …) operasyonundaki veri boyutuna bağımlı olarak işlem süresinin uzaması durumuna APPROX_COUNT_DISTINCT komutunu geliştirerek yazılım geliştiricilere  ve analistlere hızlı çalışan alternatif bir yol üretmiş durumda. Bu komut hızlı çalışıyor ancak bazı durumlarda COUNT(DISTINCT …) gibi kesin bir sonuç üretmiyor. Datanın boyutuna göre göz ardı edebilecek sapmalar ile sonucu hızlı bir şekilde buluyor.

Şimdi bu komutun performansını data boyutuna göre karşılaştırmalı olarak inceleyelim.

TEST1: 

İlk olarak testimizi 1000 kayıt ile gerçekleştiriyoruz.

CREATE TABLE appxcnt AS
SELECT mod(LEVEL,10) AS groupno,
  'TestData'
  ||LEVEL AS datacontent
FROM dual
  CONNECT BY LEVEL <1000;

Evet tablomuzu yarattık. Şimdi her 2 şekilde de test etmeye başlayabiliriz.

SET TIMING ON;
SELECT count(DISTINCT groupno) FROM appxcnt;

cnt

SET TIMING ON;
SELECT approx_count_distinct(groupno) FROM appxcnt;

apx1

 

Evet 1000 kayıt için herhangi bir fark oluşmadı diyebiliriz. İki işlemde neredeyse aynı sürede ve tamamen doğru hesaplanmış bir biçimde bitti.

 

TEST2: 

Şimdi testimizi 1.000.000 kayıt ile farklı bir SQL ile yapalım ve sonucuna bakalım.

CREATE TABLE appxcnt AS
SELECT mod(LEVEL,39182) AS groupno,
  'TestData'
  ||LEVEL AS datacontent
FROM dual
  CONNECT BY LEVEL <1000000;

Evet tablomuzu yarattık. Şimdi her 2 şekilde de test etmeye başlayabiliriz.

SET TIMING ON;
SELECT count(DISTINCT groupno) FROM appxcnt;

cnt2

SET TIMING ON;
SELECT approx_count_distinct(groupno) FROM appxcnt;

apx2

 

Bu testimizde count(Distinct)’li sorgumuz beklendiği üzere daha uzun çalıştı ve sonucu tam olarak doğru buldu. APPROX_COUNT_DISTINCT’li sorgumuz daha hızlı çalıştı ancak sonucu tam olarak doğru bulamadı. Yaklaşık bir değerle sonucu hesaplayabildi.

Testlerimizden de anlaşılacağı gibi data’nın boyutu büyüdükçe 2 fonksyion arasındaki çalışma süreleri farkinin açılacağını ve APPROX_COUNT_DISTINCT komutunun gerçek distinct değere bir miktar daha uzaklaşacağını söylemek yanlış bir tespit olmayacak.

APPROX_COUNT_DISTINCT fonksiyosnu parametre olarak BFILE, BLOB, LONG, NCLOB, LONG RAW, CLOB veri tipleri haricindeki veri tipleri ile çalışabilmekte. Distinct değer hesaplarken de NULL değerleri ignore ederek gereiye NUMBER tipinde bir değer döndürür.

Son olarak fikir vermeve yorumlama  açısından 2 fonksyonunda Explain Planını paylaşıyorum.

COUNT(Distinct)

cntexp

 

 

APPROX_COUNT_DISTINCT

appxExp

 

 

 

 

 

Daha detaylı test sonuçları ve bilgi için kaynaklar kısmında paylaştığım linkler takip edilebilir. Umarım farkındalık anlamında faydalı bir yazı olmuştur.

KAYNAKLAR

http://docs.oracle.com/database/121/SQLRF/functions013.htm#SQLRF56900

http://antognini.ch/2014/10/the-approx_count_distinct-function-a-test-case/

 

Advertisements

About ... from Emrah METE

Bilgisayar Mühendisi
This entry was posted in Oracle, Uncategorized and tagged , , , , . Bookmark the permalink.

One Response to APPROX_COUNT_DISTINCT

  1. Pingback: Oracle 12c Release 2 ile beraber SQL ve PL/SQL Tarafında Gelen Yenilikler | Emrah METE

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s