nudziło mi się :)
tabela
Kopiuj
CREATE TABLE test_table (
test_date DATE);
indeksy, można zrobić test bez i z
Kopiuj
CREATE INDEX idx_test_table_date1 ON test_table (to_char(test_date, 'YYYY/MM'));
CREATE INDEX idx_test_table_date2 ON test_table (extract(year from test_date), extract(month from test_date));
CREATE INDEX idx_test_table_date3 ON test_table (test_date);
testowe dane
Kopiuj
DECLARE
i NUMBER;
BEGIN
FOR i IN 1..1000000 LOOP
INSERT INTO test_table(test_date) VALUES(TO_DATE(TRUNC(DBMS_RANDOM.VALUE(TO_CHAR(DATE '1800-01-01','J'),TO_CHAR(DATE '2100-12-31','J'))),'J'));
END LOOP;
END;
/
procedura testowa
Kopiuj
declare
c sys_refcursor;
v_num_tab dbms_sql.number_table;
v_start_time number;
v_end_time number;
begin
v_start_time := dbms_utility.get_time;
for i in 1..100000
loop
open c for select 1 from test_table WHERE extract(year from test_date) = 2016 AND extract(month from test_date) = 6;
loop
fetch c bulk collect into v_num_tab limit 500;
exit when c%notfound;
end loop;
close c;
end loop;
v_end_time := dbms_utility.get_time;
dbms_output.put_line('EXTRACT : ');
dbms_output.put_line((v_end_time - v_start_time) / 100);
v_start_time := dbms_utility.get_time;
for i in 1..100000
loop
open c for select 1 from test_table WHERE to_char(test_date, 'YYYY/MM') = '2016/06';
loop
fetch c bulk collect into v_num_tab limit 500;
exit when c%notfound;
end loop;
close c;
end loop;
v_end_time := dbms_utility.get_time;
dbms_output.put_line('TO_CHAR : ');
dbms_output.put_line((v_end_time - v_start_time) / 100);
v_start_time := dbms_utility.get_time;
for i in 1..100000
loop
open c for select 1 from test_table WHERE test_date BETWEEN To_Date('2016.06.01', 'yyyy.mm.dd') AND To_Date('2016.06.30', 'yyyy.mm.dd');
loop
fetch c bulk collect into v_num_tab limit 500;
exit when c%notfound;
end loop;
close c;
end loop;
v_end_time := dbms_utility.get_time;
dbms_output.put_line('BETWEEN : ');
dbms_output.put_line((v_end_time - v_start_time) / 100);
end;
/
bez indeksów radzę zmienić w pętlach 100000
na 100
:)
wynik z indeksami:
Kopiuj
Line Pos Text
4 PL/SQL block, executed in 17.426 sec.
EXTRACT :
5,85
TO_CHAR :
5,76
BETWEEN :
5,8
Total execution time 17.442 sec.
Kopiuj
Line Pos Text
4 PL/SQL block, executed in 17.274 sec.
EXTRACT :
5,85
TO_CHAR :
5,69
BETWEEN :
5,73
Total execution time 17.495 sec.
wynik bez indeksów
Kopiuj
Line Pos Text
4 PL/SQL block, executed in 32.399 sec.
EXTRACT :
11,9
TO_CHAR :
18,58
BETWEEN :
1,9
Total execution time 32.624 sec.
W planach nie ma nic nadzwyczajnego
EXTRACT
Kopiuj
-------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
-------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 93 | 2418 | 3 |
| 1 | INDEX RANGE SCAN| IDX_TEST_TABLE_DATE2 | 93 | 2418 | 3 |
-------------------------------------------------------------------------
TO_CHAR
Kopiuj
-------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
-------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9335 | 46675 | 3 |
| 1 | INDEX RANGE SCAN| IDX_TEST_TABLE_DATE1 | 9335 | 46675 | 3 |
-------------------------------------------------------------------------
BETWEEN
Kopiuj
-------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
-------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 258 | 2322 | 3 |
| 1 | INDEX RANGE SCAN| IDX_TEST_TABLE_DATE3 | 258 | 2322 | 3 |
-------------------------------------------------------------------------