Avatar billede elskermad.dk Nybegynder
02. oktober 2006 - 09:58 Der er 7 kommentarer og
1 løsning

Hvordan laver man indexs?

Hej Eksperter!

Jeg har et par store tabeller som efterhånden er gået hen og være ret så langsomme at hente data fra...

Hvordan laver man index på dem?

Jeg har fx nedenstående tabel hvor jeg primært laver wheres på kolonnen ordre:

CREATE TABLE tabel (
  id int(12) NOT NULL auto_increment,
  ordre int(12) NOT NULL default '0',
  auktion int(12) NOT NULL default '0',
  bruger int(12) NOT NULL default '0',
  antal int(12) NOT NULL default '1',
  bud decimal(12,2) NOT NULL default '0.00',
  varenr varchar(55) NOT NULL default '',
  navn varchar(55) NOT NULL default '',
  tidspunkt int(12) NOT NULL default '0',
  PRIMARY KEY  (id)
) TYPE=MyISAM;


Der er ca. 200.000 rækker i tabellen


Jeg har også nedenstående tabel hvor jeg primært laver wheres på id og status

CREATE TABLE tabel2 (
  id int(12) NOT NULL auto_increment,
  status int(1) NOT NULL default '1',
  brugernavn varchar(55) NOT NULL default '',
  password varchar(55) NOT NULL default '',
  mail varchar(55) NOT NULL default '',
  navn varchar(55) NOT NULL default '',
  adresse varchar(255) NOT NULL default '',
  postnr int(5) NOT NULL default '0',
  postby varchar(55) NOT NULL default '',
  tlf int(8) NOT NULL default '0',
  mobil int(8) NOT NULL default '0',
  opret_time int(12) NOT NULL default '0',
  opret_ip varchar(15) NOT NULL default '',
  stat_referer varchar(255) NOT NULL default '',
  stat_tipper int(12) NOT NULL default '0',
  stat_kob int(12) NOT NULL default '0',
  tipkode varchar(6) NOT NULL default '',
  lev_navn varchar(55) NOT NULL default '',
  lev_att varchar(55) NOT NULL default '',
  lev_adresse varchar(255) NOT NULL default '',
  lev_postnr int(5) NOT NULL default '0',
  lev_postby varchar(55) NOT NULL default '',
  lev_land varchar(55) NOT NULL default 'Danmark',
  PRIMARY KEY  (id)
) TYPE=MyISAM;

Altså hvilke sql-kommandoer skal jeg bruge?

På forhånd tak :)
Avatar billede bromer Nybegynder
02. oktober 2006 - 11:48 #1
Du kan lave det første index med:

CREATE INDEX my_idx ON tabel(ordre);

Ellers se under CREATE INDEX i manualen. Andre indexes laves på samme måde. Men det er ikke altid at et index hjælper. Hvor meget data henter du ud med eet query? Hvis du for eksmpel henter 50.000 rækker ud, vil det være hurtigere for MySQL at lave et seq. scan (som den gør nu) end at benytte et index.
Avatar billede elskermad.dk Nybegynder
02. oktober 2006 - 12:16 #2
hvad bruger man navnet my_idx til? fremtidig vedligeholdelse?

jeg har fx denne forespørgsel som bliver brugt tit og er rimelig kompliceret.

hvor vil du lave indexs?

SELECT a.*,b.url,COUNT(ab.id) as bud FROM auktion a INNER JOIN billede b ON a.info_billede = b.id LEFT JOIN auktion_bud ab ON a.id = ab.auktion WHERE a.status = 2 AND (a.slut > $fra AND a.slut > $phptime) GROUP BY a.id ORDER BY a.slut ASC LIMIT 0,50

eller denne:
SELECT ab.*,k.brugernavn FROM auktion_bud ab INNER JOIN kunde k ON k.id = ab.bruger WHERE ab.auktion = '$auktion' ORDER BY ab.bud DESC LIMIT 0,10
Avatar billede elskermad.dk Nybegynder
02. oktober 2006 - 12:17 #3
hvordan virker sådan et index så? skal man løbende holde den opdateret, eller klare den det selv?
Avatar billede elskermad.dk Nybegynder
02. oktober 2006 - 12:24 #4
fx hvis man bruger phpmyadmin så spørger dem om følgende:

indeksnavn: valgfri
indekstype: index|unique|fulltext
feltnavn: de forskellige felter
størrelse: valgfri


altså det må vel være:
indeksnavn: mit_navn
indekstype: index
feltnavn: ordre
størrelse: ?
Avatar billede arne_v Ekspert
02. oktober 2006 - 13:05 #5
den opdaterer selv
Avatar billede bromer Nybegynder
02. oktober 2006 - 15:39 #6
elskermad.dk> Som arve skriver bliver et index vedligeholdt når der sker ændringer i tabellen. Det betyder også at, hvis din tabel modtager langt flere updates, delete og inserts i forhold til select-mængden, så vil der være et betydentlig overhead i at vedligeholde dit index.

De 2 sql querys du giver kan sikkert sagtens optimeres ret meget ved brug af indexes. Jeg vil anbefale dig at sætte "EXPLAIN" foran din SELECT. Så vil MySQL give dig en execution plan, som beskriver, hvordan databasen vil udføre din query. Du kan eventuelt paste den her, så kan vi forklare, hvad du skal være opmærksom på.

Rune
Avatar billede elskermad.dk Nybegynder
02. oktober 2006 - 15:58 #7
EXPLAIN SELECT a . * , b.url, COUNT( ab.id ) AS bud
FROM vinderland_auktion a
INNER JOIN vinderland_billede b ON a.info_billede = b.id
LEFT JOIN vinderland_auktion_bud ab ON a.id = ab.auktion
WHERE a.status =2
AND (
a.slut >0
AND a.slut > UNIX_TIMESTAMP( NOW( ) )
)
GROUP BY a.id
ORDER BY a.slut ASC
LIMIT 0 , 50



Beskrivelsen siger mig desværre ikke ret meget:
id  select_type  table  type  possible_keys  key  key_len  ref  rows  Extra 
1 SIMPLE a ALL NULL NULL NULL NULL 117 Using where; Using temporary; Using filesort
1 SIMPLE b eq_ref PRIMARY PRIMARY 4 alvision_dk_db1.a.info_billede 1 
1 SIMPLE ab ALL NULL NULL NULL NULL 72
Avatar billede elskermad.dk Nybegynder
02. oktober 2006 - 15:59 #8
I den sidste sql her vil der kun blive postet til tabellen én gang dagligt også ellers hentet fra den +100.000 gange om døgnet
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester