Özet: Sorgularda sıklıkla görülen, yanlış tip’te değer girilmesinin olumsuz etkileri anlatılıyor. Örneğin, kolon tipi “number” iken, sorguların “varchar2” olarak gönderilmesi gibi.
Sorgularımızda kullandığımız tabloların kolon veri tiplerine göre değer atamasını doğru şekilde yapmazsak sorgumuz tablo üzerindeki mevcut index’leri kullanamaz ve sorgumuz performanslı çalışmayacak, uzun sürecektir. Bazı durumlarda veri tipi çevirilerine ihtiyaç duyabiliriz. Implicit ve Explicit Conversion olarak 2 türlü veritipi çevirimi söz konusu.
Sorgularımızın performanslı çalışması için olması gereken explicit conversion’ dır ve implicit conversion’dan kaçınmalıyız.
Bu çok önemli bir konudur, zira birçok kez “yanlış veri tipi değer ataması” kullanımıdan dolayı sorgularda yavaşlık sorunları karşımıza çıkar. (implicit conversion)
Aşağıdaki örnekle ikisinin farkını yakından görelim;
Deneme amaçlı t1 tablosunu ve karakter veri tipinde (varchar2) olan id kolonu üzerine de index oluşturuyorum;
create table t1 (id varchar2(100));
create index ix_id on t1 (id);
Random olarak 10000 adet veri insert ediyorum;
begin for j in 1..10000 loop insert into t1 values(dbms_random.random); end loop; commit; end;
Dilerseniz tablonun istatistiğini toplayabilirsiniz;
EXEC dbms_stats.gather_table_stats(USER, 't1', cascade => TRUE, estimate_percent => NULL);
select * from t1;
desc t1; TABLE t1 Name Null? Type ----------------- ID VARCHAR2(100)
Explicit conversion
Sorgumda koşulda kullandığım kolonun veri tipi ne ise olması gerektiği gibi o veri tipinden değer ataması yaptığımda index’i gayet güzel kullandığını ve cost’unun da 1 olduğunu görüyorum.
Yani “explicit conversion” a sebep olup, sorguyu beklenen performansta çalıştırmış oluyorum.
SELECT * FROM t1 WHERE id='658713083';
Aşağıdaki gibi sqlplus üzerinden de görülebilir;
SQL> SET autotrace ON SQL> SELECT * FROM t1 WHERE id='658713083'; ID ------------------------------------------------------- 658713083 Execution Plan -------------------------------------------------------- Plan hash value: 531999125 -------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 11 | 1 (0)| 00:00:01 | |* 1 | INDEX RANGE SCAN| IX_ID | 1 | 11 | 1 (0)| 00:00:01 | -------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - access("ID"='658713083') Note ----- - automatic DOP: skipped because of IO calibrate statistics are missing Statistics ------------------------------------------------------- 1 recursive calls 0 db block gets 3 consistent gets 0 physical reads 0 redo size 527 bytes sent via SQL*Net to client 520 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed
İmplicit conversion
Sorgumda koşulda kullandığım kolonun veri tipi dışında number olarak değer ataması yaptığımda ise index’i kullanAMAdığını ve cost’unun da yükselip 9 olduğunu görüyorum.
Yani “implicit conversion” a neden olup, sorgu performasını çok düşürüyorum.
Sizler de kendi sorgularınızda olması gerektiğinin dışında veri tipi ataması yaparak farkını görebilirsiniz.
SELECT * FROM t1 WHERE id=658713083;
Aşağıdaki gibi sqlplus üzerinden de görülebilir;
SQL> SELECT * FROM t1 WHERE id=658713083; ID ------------------------------------------------------- 658713083 Execution Plan ------------------------------------------------------- Plan hash value: 3617692013 -------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time -------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 11 | 9 (0)| 00:00:01 |* 1 | TABLE ACCESS STORAGE FULL| T1 | 1 | 11 | 9 (0)| 00:00:01 --------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - storage(TO_NUMBER("ID")=658713083) filter(TO_NUMBER("ID")=658713083) Note ----- - automatic DOP: skipped because of IO calibrate statistics are missing Statistics ------------------------------------------------------- 1 recursive calls 0 db block gets 31 consistent gets 0 physical reads 0 redo size 527 bytes sent via SQL*Net to client 520 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed SQL>