Just nu i M3-nätverket
Gå till innehåll

Optimering av SQL join av två tabeller


Marcus Svensson

Rekommendera Poster

Marcus Svensson

Har ett litet problem här,

jag har en databas där data skrivs och läses rätt så mycket.

 

tabellerna innehåller nyheter och den ena tabellen inehåller information som man söker på, den andra innehåller själva datan som skall visas för användaren.

 

strukturen för tabellerna ser ut så här:

CREATE TABLE war_news (
 id mediumint(8) unsigned NOT NULL auto_increment,
 userid mediumint(8) unsigned NOT NULL default '0',
 unixtime int(16) unsigned NOT NULL default '0',
 type tinyint(1) unsigned NOT NULL default '0',
 new enum('0','1') NOT NULL default '1',
 PRIMARY KEY  (id),
 KEY userid (userid,new)
) TYPE=MyISAM;
# --------------------------------------------------------

#
# Table structure for table `war_news_data`
#

CREATE TABLE war_news_data (
 news_id mediumint(8) unsigned NOT NULL default '0',
 sender varchar(60) binary NOT NULL default '',
 title varchar(100) binary NOT NULL default '''No Title''',
 body text NOT NULL,
 PRIMARY KEY  (news_id)
) TYPE=MyISAM;

 

och själva SQL anropet jag kör med ser ut såhär:

SELECT a.unixtime,b.sender,b.title,b.body FROM war_news a,war_news_data b WHERE b.news_id=a.id AND (a.userid='1' AND a.new='1') GROUP BY a.id ORDER BY a.id ASC

 

 

Själva tabellerna kan innehålla mer än ett par hundra tusen poster, och nu när jag har drygt 80'000 poster så tar queryn ungefär 0.5-2sek att genomföra beroende på hur upptagen servern är. Någon som kan ge förslag på hur jag skall förbättra prestandan i detta fallet?

 

innan hade jag all data i en tabell men jag delade upp det i två istället eftersom att ha allt i en tabell gick lite väl slött ibland

 

Tack på förhand

 

</\>

<||> Marcus Svensson

<||> http://www.world-of-war.com

<||> matrx@home.se

<\/>

 

[inlägget ändrat 2003-01-16 18:25:59 av Svenneman]

[inlägget ändrat 2003-01-16 18:26:29 av Svenneman]

Länk till kommentar
Dela på andra webbplatser

DanielCarlsson

Tjenna

 

Det är väldigt svårt att ge direkta tips på en sådan fråga. Det är lite problematiskt att reda ut exempelvilken exekveringsplan optimeraren använder då jag inte har tillgång till representativ data men några tips kan jag ge.

 

Det bör dock nämnas att jag inte är någon MySQL guru, Oracle passar mig egentligen bättre.

 

1. Se till att det finns index på fälten som du joinar.

 

2. Se även till så att du har index på de fälten som används i where satsen.

 

3. Kontrollera att tabeller och index är analyserade. Är de inte analyserade kommer inte optimeraren att veta vilken exekveringsplan som är den effektivaste.

 

4. Kör explain på din sql-sats så att du ser att du får den exekveringsplanen du förväntar dig.

 

Ett annat generellt tips är att inte vara rädd för att lägga in NULL i ett fält. Det är meningslöst och prestandanedsättande att lägga in tom eller "standarddata" i kolumner som lika väl kunde varit NULL.

 

Jag tänker bla på fältet war_news.userid. Jag antar att du lägger 0 som standard om inlägget görs av en icke inloggad användare. lika väl som du kollar mot 0 i din klient så kan du kolla mot NULL. Det fina i kråksången är att NULL inte tar plats i din databas medan 0 gör det. Ok jag vet att det måste att lägga in 0 i fallet då det finns ett parent/foreign-key förhållande mellan tabellerna.

 

Länk till kommentar
Dela på andra webbplatser

Och så ska man väl ha den mindre tabellen först i JOIN-villkoret, samt göra restrict ((a.userid='1' AND a.new='1')) innan join.

 

Så där är det i teorin. Om det har någon större betydelse i praktiken kan jag inte uttala mig om...

 

 

 

_________

TicoRoman - The One And Only

 

-Den vise vill veta, den dåraktige tala-

 

Länk till kommentar
Dela på andra webbplatser

DanielCarlsson

Jag vet att i oraclevärlden så fixar optimeraren detta om man har representativ statistik på tabellerna.

 

/Daniel

 

Länk till kommentar
Dela på andra webbplatser

Marcus Svensson

Tack för hjälpen, jag kände faktiskt inte till Explain satsen, lite pinsamt faktiskt hehe för jag har hållt på med mysql i drygt 2 år nu.

 

jag körde explain å med hjälp av mysql manualen kunde jag tolka vad den spottade ut. Fick optimerat koden lite iaf. Nu körs koden på ett par ms snabbare än innan, vilket gör stor skillnad när det är en välbesökt sida.

 

Tack för hjälpen alla och om ni är intresserade så har jag inkluderat den färdig a queryn här

SELECT a.unixtime,b.sender,b.title,b.body FROM war_news a,war_news_data b WHERE (a.userid=36 AND a.new='1') AND b.news_id=a.id

 

 

</\>

<||> Marcus Svensson

<||> http://www.world-of-war.com

<||> matrx@home.se

<\/>

 

Länk till kommentar
Dela på andra webbplatser

Arkiverat

Det här ämnet är nu arkiverat och är stängt för ytterligare svar.

×
×
  • Skapa nytt...