Zacheusz
Siedlecki
Senior Java
Architect, Working
Manager
Temat: Optymalizacja 11g pod jeden typ prostych zapytań [?]
W mojej pracy magisterskiej wykorzustuję bazę Oracle 11g. Podczas testów wydajnościowych okazało się, że operacje wykonywanie na bazie zajmują więcej czasu niż się tego spodziewałem. Sytuacja jest na tyle specyficzna i dobrze zdefiniowana, że wydaje mi się iż można polepszyć tą wydajność. Proszę o pomoc gdyż skończyły mi się pomysły (ograniczone przez moją wiedzę).Wykonywane są liczne, bardzo podobne do siebie selecty. Chciałbym zoptymalizować bazę właśnie pod tylko ten typ zapytań. Długość wykonywania jakichkolwiek innych ma tutaj znaczenie marginalne. Zapytanie obejmuje tylko dwie kolumny jednej tabeli. (Właściwie zmaterializowanego widoku. Widok nie jest przebudowany podczas pracy systemu więc to chyba nie ma znaczenia.)
DESCRIBE MVIEW_TRANSACTIONS;
TID NOT NULL NUMBER(19)
ITEM NOT NULL NUMBER(19)
na kolumnie ITEM jest założony index bitmapowy:
CREATE BITMAP INDEX MVIEW_TRANSACTIONS_INDEX_ITEM ON MVIEW_TRANSACTIONS;
Pary (tid, item) są unikalne. Zapytania wyglądają w ten sposób:
SELECT count(*)
FROM
(SELECT tid
FROM MVIEW_TRANSACTIONS
WHERE item IN (:1 ,:2 ,:3 ,:4) group by tid having count(*)=:5 ) subtable;
Ostatni parametr jest liczbą elementów w zbiorze. Czyli na przykład:
SELECT count(*)
FROM
(SELECT tid
FROM MVIEW_TRANSACTIONS
WHERE item IN (70 ,2573 ,2430 ,2424) group by tid having count(*)=4 ) subtable;
testowane są zbiory o różnej długości, czyli na przykład też:
SELECT count(*)
FROM
(SELECT tid
FROM MVIEW_TRANSACTIONS
WHERE item IN (71 ,2570) group by tid having count(*)=2 ) subtable;
Plan pierwszego z podanych przykładowych zapytań:
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 3439 (3)| 00:00:42 |
| 1 | SORT AGGREGATE | | 1 | | | |
| 2 | VIEW | | 3713 | | 3439 (3)| 00:00:42 |
|* 3 | FILTER | | | | | |
| 4 | HASH GROUP BY | | 3713 | 33417 | 3439 (3)| 00:00:42 |
|* 5 | MAT_VIEW ACCESS FULL| MVIEW_TRANSACTIONS | 969K| 8520K| 3411 (3)| 00:00:41 |
---------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter(COUNT(*)=4)
5 - filter("ITEM"=70 OR "ITEM"=2424 OR "ITEM"=2430 OR "ITEM"=2573)
Tutaj szczegółowe wyjaśnienie planu z EM: http://zacheusz.eu/various/plan.html (wykonany na większym zbiorze)
W czasie wykonywania tych zapytań nie potrzebuję transakcji. Baza jest uruchomiona w trybie tylko do odczytu (co nie jest konieczne):
startup mount;
alter database open read only;
W ostateczności można nawet założyć, że długość zbioru nie przekracza 10 a w kolumnie ITEM występuje 100 wartości.
Będę niezmiernie wdzięczny za wszelkie profesjonalne rady i pomysły.Zacheusz Siedlecki edytował(a) ten post dnia 16.12.09 o godzinie 09:50