Database traag
Zit met een porbleem dat mijn mysql database traag lijkt te reageren.
Het is lastig te reproduceren omdat het niet constant is.
Ik denk nu te hebben achterhaald wanneer de traagheid optreed;
De database betreft een forum, wanneer iemand bijvoorbeeld een reactie heeft geplaatst in een topic en daarna de forum-pagina opvraagt duurt het erg lang voordat de pagina is geladen.
Heeft iemand tips hoe of wat ik kan testen?
Alvast dank..
Daniël
Weet je zeker dat het aan je database ligt? Is het niet gewoon op bepaalde momenten drukker op je website?
Probeer de trage query te identificeren en ga ermee testen, explains maken. Het kan bijvoorbeeld traag worden door overmatige full-table scans op grote tabellen. Inefficiente query's moet je onderzoeken en optimaliseren. Ook als het druk is op je website is een prima performance van je database mogelijk maar dan wel met efficiente sql.
Aad B op 29/02/2012 21:50:25:
Probeer de trage query te identificeren en ga ermee testen, explains maken. Het kan bijvoorbeeld traag worden door overmatige full-table scans op grote tabellen. Inefficiente query's moet je onderzoeken en optimaliseren. Ook als het druk is op je website is een prima performance van je database mogelijk maar dan wel met efficiente sql.
Hoe kan ik achter de trage query's komen?
Zoeken in je php code, daar waar iemand bijvoorbeeld een reactie heeft geplaatst in een topic en daarna de forum-pagina opvraagt. Vaak veel zoekwerk en query's los proberen. Is niet 1-2-3 even een oplossing voor te noemen.
MySQL instellen dat hij queries die langer dan een x aantal seconden logt. Deze logs kan je vervolgens weer gebruiken om de langzame queries op te sporen. Vaak zijn het de queries die je niet verwacht die heel traag kunnen zijn.
Een goede manier om een query te analyseren is door EXPLAIN te gebruiken. Hiermee krijg je precies te zien wat een query doet. Of er indices gebruikt worden en hoeveel records er gelezen moeten worden voor een query.
Een laatste stap om te controleren is hoeveel queries er op een pagina uitgevoerd worden. Het kan best zijn dat je heel efficiënte queries hebt, maar als je er heel erg veel uitvoert, zal het toch heel traag kunnen worden.
Je kan in Een goede manier om een query te analyseren is door EXPLAIN te gebruiken. Hiermee krijg je precies te zien wat een query doet. Of er indices gebruikt worden en hoeveel records er gelezen moeten worden voor een query.
Een laatste stap om te controleren is hoeveel queries er op een pagina uitgevoerd worden. Het kan best zijn dat je heel efficiënte queries hebt, maar als je er heel erg veel uitvoert, zal het toch heel traag kunnen worden.
Veel queries op een pagina kunnen komen doordat er queries in een loop worden uitgevoerd. Zo lijkt het in eerste instantie niet veel; maar worden het er eigenlijk steeds meer.
Op een index van een forum kan ik me deze situatie zomaar voorstellen: ophalen alle categorieën, daarvan laatste topic(s), daarvan laatste reactie en/of de gebruiker; zulke loops.
Bedankt voor jullie reactie. Mijn SQL kennis is niet echt groot. Is er niet tooling die dit voor me kan doen?
Ja, vrees enkel dat dit niet gaat werken. SQL databases draaien bij mijn hoster. Ik ga nog even kijken. Dank
Ik heb toevallig onlangs een paar trage queries gehad.
Dit lag in mijn geval aan het gebruik van "IN", "NOT IN" en "EXISTS"
Ik heb deze statements vervangen door "JOINS" en dat verhielp het probleem.
De code:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
<? if(empty($_GET['pagina']))
header("location: ../../content.php?pagina=forum/forum");
$select = "SELECT * FROM forum_categorieen ORDER BY naam";
$query = mysql_query($select)or die(mysql_error());
if(mysql_num_rows($query) == 0)
{
echo "<div class=\"titel\">Fout</div>";
echo "<div class=\"bericht\">Er zijn nog geen forumcategorieen aangemaakt...</div>";
}
else
{
while($list = mysql_fetch_object($query))
{
echo "<div class=\"titel\">";
echo "<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"98%\">";
echo "<tr>";
echo "<td width=\"5%\"></td>";
echo "<td width=\"45%\"><b>".htmlspecialchars($list->naam)."</b></td>";
echo "<td width=\"10%\"><b>Topics</b></td>";
echo "<td width=\"10%\"><b>Reacties</b></td>";
echo "<td width=\"30%\"><b>Laatste post</b></td>";
echo "</tr>";
echo "</table>";
echo "</div>";
echo "<div class=\"bericht\">";
echo "<table cellpadding=\"2\" cellspacing=\"0\" border=\"0\" width=\"98%\">";
$select2 = "SELECT * FROM forum_subcategorieen WHERE categorieid = '".$list->id."' ORDER BY naam";
$query2 = mysql_query($select2)or die(mysql_error());
if(mysql_num_rows($query2) == 0)
{
echo "<tr>";
echo "<td colspan=\"5\">Geen subcategorieën aanwezig...</td>";
echo "</tr>";
}
else
{
while($list2 = mysql_fetch_object($query2))
{
$select3 = "SELECT * FROM forum_onderwerpen WHERE forum = '".$list2->id."'";
$query3 = mysql_query($select3)or die(mysql_error());
$select4 = "SELECT * FROM forum_onderwerpen WHERE forum = '".$list2->id."' ORDER BY id DESC LIMIT 0,1";
$query4 = mysql_query($select4)or die(mysql_error());
$list4 = mysql_fetch_object($query4);
$select5 = "SELECT forum_reacties.datum AS datum, forum_reacties.auteur AS auteur, forum_reacties.naam_anoniem AS naam_anoniem
FROM forum_reacties JOIN forum_onderwerpen ON forum_reacties.topicid = forum_onderwerpen.id
WHERE forum_onderwerpen.forum = '".$list2->id."' ORDER BY forum_reacties.id DESC LIMIT 0,1";
$query5 = mysql_query($select5)or die(mysql_error());
$list5 = mysql_fetch_object($query5);
if(mysql_num_rows($query4) == 0 && mysql_num_rows($query5) == 0)
$laatste = "Geen";
elseif($list4->datum > $list5->datum)
{
$select6 = "SELECT * FROM leden_gegevens WHERE id = '".$list4->auteur."'";
$query6 = mysql_query($select6)or die(mysql_error());
$list6 = mysql_fetch_object($query6);
$door = $list6->gebruikersnaam;
$door = strip_tags($door);
$door = strtolower($door);
$door = ucwords($door);
if ($list6->status == "Beheerder")
$gebruikersnaam = "$door";
elseif ($list6->status == "SuperModerator")
$gebruikersnaam = "$door";
elseif ($list6->status == "Moderator")
$gebruikersnaam = "$door";
elseif ($list6->status == "Verbannen")
$gebruikersnaam = "$door";
else
$gebruikersnaam = $door;
$laatste = "Door <a href=\"content.php?pagina=leden/profiel&id=".$list6->id."\">".$gebruikersnaam."</a><br />@ ".date("d-m-Y H:i:s", strtotime($list4->datum))."";
}
else
{
if($list5->auteur != 99999999){
$select7 = "SELECT * FROM leden_gegevens WHERE id = '".$list5->auteur."'";
$query7 = mysql_query($select7)or die(mysql_error());
$list7 = mysql_fetch_object($query7);
$door = $list7->gebruikersnaam;
$door = strip_tags($door);
$door = strtolower($door);
$door = ucwords($door);
if ($list7->status == "Beheerder")
$gebruikersnaam = "$door";
elseif ($list7->status == "SuperModerator")
$gebruikersnaam = "$door";
elseif ($list7->status == "Moderator")
$gebruikersnaam = "$door";
elseif ($list7->status == "Verbannen")
$gebruikersnaam = "$door";
else
$gebruikersnaam = $door;
} else {
$gebruikersnaam = $list5->naam_anoniem;
}
$laatste = "Door <a href=\"content.php?pagina=leden/profiel&id=".$list7->id."\">".$gebruikersnaam."</a><br />@ ".date("d-m-Y H:i:s", strtotime($list5->datum))."";
}
$select8 = mysql_query("SELECT COUNT(*) FROM forum_reacties,forum_onderwerpen WHERE forum_onderwerpen.forum = '".$list2->id."' AND forum_reacties.topicid = forum_onderwerpen.id")or die(mysql_error());
$reacties = mysql_result($select8, 0);
echo "<tr onclick=\"window.location.href='content.php?pagina=forum/bekijk&id=".$list2->id."'\">";
echo "<td width=\"5%\"><img src=\"afbeeldingen/forum.gif\" alt=\"Forum\"/></td>";
echo "<td width=\"45%\"><a href=\"content.php?pagina=forum/bekijk&id=".$list2->id."\"><b>".htmlspecialchars($list2->naam)."</b></a><br />".htmlspecialchars($list2->omschrijving)."</td>";
echo "<td width=\"10%\">".mysql_num_rows($query3)."</td>";
echo "<td width=\"10%\">".$reacties."</td>";
echo "<td width=\"30%\">".$laatste."</td>";
echo "</tr>";
}
}
echo "</table></div>";
}
}
?>
header("location: ../../content.php?pagina=forum/forum");
$select = "SELECT * FROM forum_categorieen ORDER BY naam";
$query = mysql_query($select)or die(mysql_error());
if(mysql_num_rows($query) == 0)
{
echo "<div class=\"titel\">Fout</div>";
echo "<div class=\"bericht\">Er zijn nog geen forumcategorieen aangemaakt...</div>";
}
else
{
while($list = mysql_fetch_object($query))
{
echo "<div class=\"titel\">";
echo "<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"98%\">";
echo "<tr>";
echo "<td width=\"5%\"></td>";
echo "<td width=\"45%\"><b>".htmlspecialchars($list->naam)."</b></td>";
echo "<td width=\"10%\"><b>Topics</b></td>";
echo "<td width=\"10%\"><b>Reacties</b></td>";
echo "<td width=\"30%\"><b>Laatste post</b></td>";
echo "</tr>";
echo "</table>";
echo "</div>";
echo "<div class=\"bericht\">";
echo "<table cellpadding=\"2\" cellspacing=\"0\" border=\"0\" width=\"98%\">";
$select2 = "SELECT * FROM forum_subcategorieen WHERE categorieid = '".$list->id."' ORDER BY naam";
$query2 = mysql_query($select2)or die(mysql_error());
if(mysql_num_rows($query2) == 0)
{
echo "<tr>";
echo "<td colspan=\"5\">Geen subcategorieën aanwezig...</td>";
echo "</tr>";
}
else
{
while($list2 = mysql_fetch_object($query2))
{
$select3 = "SELECT * FROM forum_onderwerpen WHERE forum = '".$list2->id."'";
$query3 = mysql_query($select3)or die(mysql_error());
$select4 = "SELECT * FROM forum_onderwerpen WHERE forum = '".$list2->id."' ORDER BY id DESC LIMIT 0,1";
$query4 = mysql_query($select4)or die(mysql_error());
$list4 = mysql_fetch_object($query4);
$select5 = "SELECT forum_reacties.datum AS datum, forum_reacties.auteur AS auteur, forum_reacties.naam_anoniem AS naam_anoniem
FROM forum_reacties JOIN forum_onderwerpen ON forum_reacties.topicid = forum_onderwerpen.id
WHERE forum_onderwerpen.forum = '".$list2->id."' ORDER BY forum_reacties.id DESC LIMIT 0,1";
$query5 = mysql_query($select5)or die(mysql_error());
$list5 = mysql_fetch_object($query5);
if(mysql_num_rows($query4) == 0 && mysql_num_rows($query5) == 0)
$laatste = "Geen";
elseif($list4->datum > $list5->datum)
{
$select6 = "SELECT * FROM leden_gegevens WHERE id = '".$list4->auteur."'";
$query6 = mysql_query($select6)or die(mysql_error());
$list6 = mysql_fetch_object($query6);
$door = $list6->gebruikersnaam;
$door = strip_tags($door);
$door = strtolower($door);
$door = ucwords($door);
if ($list6->status == "Beheerder")
$gebruikersnaam = "$door";
elseif ($list6->status == "SuperModerator")
$gebruikersnaam = "$door";
elseif ($list6->status == "Moderator")
$gebruikersnaam = "$door";
elseif ($list6->status == "Verbannen")
$gebruikersnaam = "$door";
else
$gebruikersnaam = $door;
$laatste = "Door <a href=\"content.php?pagina=leden/profiel&id=".$list6->id."\">".$gebruikersnaam."</a><br />@ ".date("d-m-Y H:i:s", strtotime($list4->datum))."";
}
else
{
if($list5->auteur != 99999999){
$select7 = "SELECT * FROM leden_gegevens WHERE id = '".$list5->auteur."'";
$query7 = mysql_query($select7)or die(mysql_error());
$list7 = mysql_fetch_object($query7);
$door = $list7->gebruikersnaam;
$door = strip_tags($door);
$door = strtolower($door);
$door = ucwords($door);
if ($list7->status == "Beheerder")
$gebruikersnaam = "$door";
elseif ($list7->status == "SuperModerator")
$gebruikersnaam = "$door";
elseif ($list7->status == "Moderator")
$gebruikersnaam = "$door";
elseif ($list7->status == "Verbannen")
$gebruikersnaam = "$door";
else
$gebruikersnaam = $door;
} else {
$gebruikersnaam = $list5->naam_anoniem;
}
$laatste = "Door <a href=\"content.php?pagina=leden/profiel&id=".$list7->id."\">".$gebruikersnaam."</a><br />@ ".date("d-m-Y H:i:s", strtotime($list5->datum))."";
}
$select8 = mysql_query("SELECT COUNT(*) FROM forum_reacties,forum_onderwerpen WHERE forum_onderwerpen.forum = '".$list2->id."' AND forum_reacties.topicid = forum_onderwerpen.id")or die(mysql_error());
$reacties = mysql_result($select8, 0);
echo "<tr onclick=\"window.location.href='content.php?pagina=forum/bekijk&id=".$list2->id."'\">";
echo "<td width=\"5%\"><img src=\"afbeeldingen/forum.gif\" alt=\"Forum\"/></td>";
echo "<td width=\"45%\"><a href=\"content.php?pagina=forum/bekijk&id=".$list2->id."\"><b>".htmlspecialchars($list2->naam)."</b></a><br />".htmlspecialchars($list2->omschrijving)."</td>";
echo "<td width=\"10%\">".mysql_num_rows($query3)."</td>";
echo "<td width=\"10%\">".$reacties."</td>";
echo "<td width=\"30%\">".$laatste."</td>";
echo "</tr>";
}
}
echo "</table></div>";
}
}
?>
Gewijzigd op 01/03/2012 16:37:10 door Daniel Bosklopper
Wellicht handig om te bedenken hoe je door eenvoudiger met minder queries op kan lossen ;)