Om du med "svar direkt" menar svar på en SELECT med unik nyckel (som unikt
pekar ut en enda post) så spelar ju inte tabellstorleken någon speciell roll alls.
Det går i princip lika snabbt oberoende på tabellstorlek. Det ökar med en eller
ett par I/O för varje gång som index djupet öker med ett. I exemplen nedan har
primärindex ett djup på 6 nivåer, det är lite onödigt mycket och skulle lätt
kunna minskas genom att öka page-storleken på indexet (sannolikt bara
satt som default från början).
> Den var såklart indexerad, men ändå.
Det är inte "men ändå". Det är fullkommligt avgörande.
Och vad betyder "svar direkt" igentligen ?
0.1, 0.01 eller 0.001 s ? Alla dessa tider skulle upplevas som "direkt"
om man bara sitter bredvid och tittar, men det är en väldig skillnad i tid!
Svarstider (i alla fall när det gäller korta tider) blir ganska
ointressanta om man inte mäter dom med något verktyg.
Jag körde ett par exempel på en tabell med ca 16,5 milj poster.
Postlängd ca 100 tecken och tar upp ca 1.6 GB utrymme.
Kört på en 666 MHz maskin, 4GB minne. Jag har ersatt de verkliga
tabell och fält namnen med dummynamn...
Kod: Markera allt
SQL> select count(*) from tab1;
16542308
1 row selected
Först en enkel select med unika nycklar :
Kod: Markera allt
SQL> set timing on;
SQL> select fld1, fld2
cont> from tab1 where fld1 = 'abcdef'
cont> and fld2 = 123456;
fld1 fld2
abcdef 123456
1 row selected
Timing: Elapsed: 0 00:00:00.05 Cpu: 0 00:00:00.00
SQL>
0.05 s "elapsed" och "CPU" inte mätbart med 10 ms upplösning. Jag fick
köra om samma SELECT ca 10 gånger för att det skulle ticka fram
en hundradels CPU sek. Så säg att varje SELECT tar ca 1 ms CPU-tid.
Så att en databas svarar "direkt" när man söker med unika nycklar
är knappast att imponeras av. Det är naturligtsvis helt förväntat.
Just i detta fall har det använda indexet
Om man däremot kör mot ett fält som inte är indexerat så blir det naturligtsvis helt annolunda :
Kod: Markera allt
SQL> select fld1, fld2
cont> from tab1 where fld3 = 86716;
fld1 fld2
abcdef 12345
abcdef 23456
...
...
abcdef 34567
abcdef 45678
140 rows selected
Timing: Elapsed: 0 00:03:04.87 Cpu: 0 00:02:43.44
Så här drog det iväg i ca 2 min och 45 sekunder, men nu är det en total
table-scan av hela tabellen med 16.5 milj poster, så det är ju ett helt annat "jobb".
Att inte totaltiden (ca 3 min) skilljer så mycket beror på att databasen "ser" att
man läser tabellen sekvensiellt och slår på "asynkron pre-fetch" automatiskt. Så
posterna läses från disk lite innan de behövs, så att säga. Databasen har hela tiden
koll på att de pre-fetchade posterna faktiskt används, om inte så slår den av
pre-fetchen igen. Det sker dynamiskt hela tiden.
Lite statistik från databasen från den senaste körningen. Först "Record Statistics" taget
mitt under körningen. Databasen har alltså som mest "kollat" på lite drygt 100.000 poster
per sekund, vilket stämmer bra med 16.5 milj / 163 sekunder...
Kod: Markera allt
Node: xxxx (1/1/1) Oracle Rdb V7.2-401 Perf. Monitor 14-FEB-2010 19:47:02.56
Rate: 1.00 Second Record Statistics Elapsed: 00:01:27.96
Page: 1 of 1 device:<yyyy.RDB_3>aaaaaDB.RDB;5 Mode: Online
────────────────────────────────────────────────────────────────────────────────
statistic......... rate.per.second............. total....... average......
name.............. max..... cur..... avg....... count....... per.trans....
record marked 0 0 0.0 0 0.0
record fetched 101260 82848 42988.1 3781234 0.3
fragmented 0 0 0.0 0 0.0
record stored 0 0 0.0 0 0.0
fragmented 0 0 0.0 0 0.0
pages checked 0 0 0.0 0 0.0
saved IO 0 0 0.0 0 0.0
discarded 0 0 0.0 0 0.0
record erased 0 0 0.0 0 0.0
fragmented 0 0 0.0 0 0.0
temp record marked 0 0 0.0 0 0.0
fetchd 0 0 0.0 0 0.0
stored 0 0 0.0 0 0.0
erased 0 0 0.0 0 0.0
sequential scan 1 0 0.0 1 0.0
record fetched 101260 82848 42988.0 3781233 0.3
Cachen räcker inte till så alla I/O går från disk ("not found: read" på sista raden nedan).
Alltså lite drygt 3000 I/O per sekund från disk. Det som kallas "fetch for read" är
antalet databas sidor ("pages") som har kollats för att hitta tabellraderna. Notera
att dessa 3000 I/O per sekund inte går fysiskt mot disk, de fångas upp av OS'ets
diskcache och det var 3-400 I/O per sekund mot fysisk disk.
Kod: Markera allt
Node: xxxx (1/1/1) Oracle Rdb V7.2-401 Perf. Monitor 14-FEB-2010 19:49:00.65
Rate: 1.00 Second PIO Statistics--Data Fetches Elapsed: 00:03:26.05
Page: 1 of 1 device:<yyyy.RDB_3>aaaa.RDB;5 Mode: Online
────────────────────────────────────────────────────────────────────────────────
statistic......... rate.per.second............. total....... average......
name.............. max..... cur..... avg....... count....... per.trans....
fetch for read 226178 200623 155749.9 32093840 3.2
fetch for write 0 0 0.0 0 0.0
in AS: all ok 222802 197292 153262.2 31581210 3.1
AS: need lock 0 0 0.0 0 0.0
AS: old version 0 0 0.0 0 0.0
in GB: need lock 2 0 0.0 3 0.0
GB: old version 0 0 0.0 0 0.0
GB: transferred 0 0 0.0 0 0.0
not found: read 3484 3331 2487.7 512627 0.0
synth 0 0 0.0 0 0.0
Vad som är bra eller dåligt här kan vara lite svårt att säga. Det beror mycket
på miljön sm det hela körs i o.s.v.