Oracle adatbázis lekérdezés készítés elvei
🔍 Hogyan deríthetem ki egy tábla indexeit?
A következő lekérdezések segítenek feltérképezni egy tábla indexeit:
1. Indexek lekérdezése:
--- sqlSELECT index_name, uniqueness, statusFROM user_indexes
WHERE table_name = 'TÁBLA_NÉV';
2. Index oszlopainak lekérdezése:
--sqlSELECT index_name, column_name, column_positionFROM user_ind_columns
WHERE table_name = 'TÁBLA_NÉV'
ORDER BY index_name, column_position;
🎯 Mely mezőket érdemes keresésre használni?
-
Indexszel ellátott mezők – ezek a legjobb jelöltek a WHERE feltételekhez.
-
Szelektivitás – ha egy oszlop sok különböző értéket tartalmaz (pl. személyi szám), jó jelölt indexhez. Ha kevés értéket (pl. "ország = 'HU'"), akkor kevésbé hatékony.
-
Használati gyakoriság – ha egy oszlop gyakran szerepel szűrésre vagy JOIN feltételekben, akkor érdemes indexelni.
⚙️ Tippek gyors lekérdezéshez (optimalizálás):
-
Használj
EXPLAIN PLAN
vagyAUTOTRACE
: Ezekkel megnézheted, hogyan hajtódik végre a lekérdezés.---sqlEXPLAIN PLAN FORSELECT * FROM employees WHERE department_id = 10; SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
-
Kerüld a függvényeket az indexelt oszlopokon: Ez megakadályozza az index használatát.
-
🛑:
WHERE UPPER(name) = 'JOHN'
-
✅:
WHERE name = 'John'
(ha van index aname
mezőn)
-
-
Használj bővített statisztikákat (gather stats): Oracle optimalizáló jobban dönt, ha friss statisztikák vannak.
---sqlEXEC DBMS_STATS.GATHER_TABLE_STATS('SCHEMA', 'TÁBLA_NÉV'); -
Index típusok:
-
B-Tree index: általános esetekre jó (egyenlőség, tartománykeresés).
-
Bitmap index: kevés különböző érték esetén jó (pl. „nem”, „ország”).
-
Composite index: több mezőt tartalmaz, a sorrend fontos!
-
🧠 Jó gyakorlatok
-
Törekedj minél szelektívebb szűrésre.
-
JOIN-okat mindig indexelt mezőkön végezd.
-
Használj aliasokat és legyen jól olvasható a lekérdezés.
-
Ne kérj le felesleges oszlopokat (
SELECT *
helyett név szerint).
🗃️ Példatáblák:
-
CUSTOMERS (1 millió sor)
---sqlcustomer_id (PK, indexed), name, country_code, created_date -
ORDERS (10 millió sor)
---sqlorder_id (PK), customer_id (FK -> CUSTOMERS), order_date, status, total_amount -
PRODUCTS (100 ezer sor)
---sqlproduct_id (PK), name, category, price -
ORDER_ITEMS (100 millió sor)
---sqlorder_item_id (PK), order_id (FK -> ORDERS), product_id (FK -> PRODUCTS), quantity, unit_price
🔍 Példa 1: Egyszerű lekérdezés ügyfelekre szűréssel
❌ Rossz megoldás:
---sql
SELECT *
FROM customers
WHERE UPPER(name) = 'JOHN SMITH';
-
Miért rossz?
-
UPPER(name)
miatt nem használható az index aname
oszlopon. -
SELECT *
feleslegesen lekéri az összes oszlopot.
-
✅ Jó megoldás:
---sqlSELECT customer_id, nameFROM customers
WHERE name = 'John Smith';
-
Miért jobb?
-
Index használható.
-
Csak szükséges oszlopokat kér le → kevesebb I/O.
-
🔍 Példa 2: Részletes jelentés vevői rendelésekből
❌ Rossz megoldás (JOIN + funkcióval + nincs index):
---sqlSELECT c.name, o.order_date, o.total_amountFROM customers c
JOIN orders o ON c.customer_id = o.customer_id
WHERE TO_CHAR(o.order_date, 'YYYY-MM') = '2024-04';
-
Miért lassú?
-
TO_CHAR
megakadályozza az index használatátorder_date
mezőn. -
Nagy táblák között történik a szűrés után.
-
✅ Jó megoldás:
---sqlSELECT c.name, o.order_date, o.total_amountFROM customers c
JOIN orders o ON c.customer_id = o.customer_id
WHERE o.order_date BETWEEN DATE '2024-04-01' AND DATE '2024-04-30';
-
Előny:
-
Indexelhető a
order_date
. -
Helyes szűrés dátumtartományon → gyorsabb.
-
🔍 Példa 3: Aggregált riport rendelés részletekkel
❌ Rossz megoldás (nem szelektív JOIN):
---sqlSELECT c.country_code, SUM(oi.quantity * oi.unit_price) as revenue
FROM customers c
JOIN orders o ON c.customer_id = o.customer_id
JOIN order_items oi ON o.order_id = oi.order_id
GROUP BY c.country_code;
-
Mi a gond?
-
Feleslegesen sok adatot kapcsol össze.
-
Ha
country_code
nincs indexelve, a GROUP BY lassú lehet.
-
✅ Jó megoldás (előszűrés és statisztikák):
sql-- Index legyen a customers.country_code és orders.order_date mezőkön!
SELECT c.country_code, SUM(oi.quantity * oi.unit_price) as revenue
FROM customers c
JOIN orders o ON c.customer_id = o.customer_id
JOIN order_items oi ON o.order_id = oi.order_id
WHERE o.order_date >= SYSDATE - 365
GROUP BY c.country_code;
-
Előnyök:
-
Év szintű előszűrés szűkíti az adathalmazt.
-
Indexek gyorsítják a kapcsolódást és szűrést.
-
⚡ Optimalizálás eszközökkel:
1. Explain Plan
---sqlEXPLAIN PLAN FOR
SELECT ... ;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
Megmutatja, melyik művelet mennyibe kerül.
2. AUTOTRACE (SQL*Plus):
---sqlSET AUTOTRACE ON;
SELECT ... FROM ...;
3. Statisztikák frissítése:
---sqlEXEC DBMS_STATS.GATHER_TABLE_STATS('SCHEMA', 'ORDERS');
🧠 Összefoglaló jó gyakorlatok nagy táblákon:
Rossz gyakorlat | Jó gyakorlat |
---|---|
SELECT * | Csak szükséges oszlopokat kérj le |
Függvény indexelt oszlopon | Kerüld a TO_CHAR , UPPER , stb. |
Nincs szűrés nagy JOIN előtt | Szűrj minél korábban |
Nincs index | Indexelj szűrésre és JOIN mezőkre |
Elavult statisztikák | Használj DBMS_STATS.GATHER_* rutinokat |
Nem használsz EXPLAIN PLAN-t | Mindig ellenőrizd a végrehajtási tervet |
Megjegyzések
Megjegyzés küldése