Date post: | 07-Apr-2017 |
Category: |
Technology |
Upload: | harald-zeitlhofer |
View: | 258 times |
Download: | 2 times |
Lettheblamegamestart!
WebServer ApplicationServer Database
DEV Team DBA Team
Blame the database for all performance issues
Blame the SW/HW or system administrators
Network?
function roomReservationReport($room)
{
$reservations = loadDataForRoom($room->id);
return generateReport($room, $reservations);
}
SlowReport
function roomReservationReport($room)
{
$tstart = microtime(true);
$reservations = loadDataForRoom($room->id);
$dataLoadTime = microtime(true) - $tstart;
return generateReport($room, $reservations);
}
DEVteamaddlogoutput
45sDEVteamresult
<1msDBAteamlooksatDBstatsperquery
ExcessiveSQL:24889!CallstoDatabase
DatabaseHeavy:66.51%(40.27s)
TimeSpentinSQLExecs
Server/Infrastructure
DBQueries
Applicationdesign
DBDesignDatabase
Performancehotspots
DatabasePerformanceHotspots
Application Design Database Infrastructure
http://apmblog.dynatrace.com/2015/06/25/when-old-jira-tickets-killed-our-productivityuser-experience/
Toomanydatabasequeries
Exercise:createlistofcourses
Createlistofcourses$schools = new SchoolEntities();
foreach ($schools as $school) {
foreach ($school->departments as $department) {
foreach ($department->courses as $course) {
echo $department->name . ": " . $course->title;
}
}
} • 10schools• 20departmentsperschool• 50cursesperdepartment
N+1problem• 10schools• 20departmentsperschool• 50cursesperdepartment
=>10x20x50=10001singledatabasestatements!!!
UseaJOINquery$rows = $db->query ("
select department.name as department, course.title as course
from school
join department on school_id = school.id
join course on department_id = department.id
");
foreach ($rows as $row) {
echo $row->department . ": " . $row->course;
}
=>ONEdatabasestatement!!!
Retrievingtoomanyrecords
Retrievingtoomanyrecords$schools = new SchoolEntities();
foreach ($schools->departments as $department) {
foreach ($department->courses as $course) {
if ($course->category == "SQL" &&
$course->level == "expert") {
echo $department->name . ": " . $course->title);
}
}
}
=>3records,still10001queries
UseaJOINquery$rows = $db->query ("
select department.name as department, course.title as course
from school
join department on school_id = school.id
join course on department_id = department.id
where course.category = 'SQL' and course.level = 'expert'
");
foreach ($rows as $row) {
echo $department . ": " . $course);
}
=>ONEdatabasestatement!!!
Caching
MySQLQueryCache• Cachesqueryresultsinmemory
OracleSQLCache• OracleSQLcachestorestheexecutionplanforaSQLstatement• Evendifferentplansastoredfordifferentbindvariablevalues• Noparsingrequired• ParsingisthemostCPUconsumingprocess• CachekeyisfullSQLquerytext
select * from country where code = 'AT'
!=
SELECT * from country where code = 'AT'
OracleSQLCache<?php
$db = new PDO('oci:dbname=sid', 'username', 'password');
$data = Array();
$data[] = $db->query("select * from country where code = 'AT'");
$data[] = $db->query("select * from country where code = 'AU'");
$data[] = $db->query("select * from country where code = 'NZ'");
$data[] = $db->query("select * from country where code = 'ES'");
?>
?>
OracleSQLCache<?php
$db = new PDO('oci:dbname=sid', 'username', 'password');
$data = Array();
$ps = $db->prepare("select * from country where code = :code");
$data[] = $ps->exec(array("code" => "AT"));
$data[] = $ps->exec(array("code" => "AU"));
$data[] = $ps->exec(array("code" => "NZ"));
$data[] = $ps->exec(array("code" => "ES"));
?>
DatabaseHealth
Indexes
Indexesaredatastructuresforreferencingasearchvalue(inanindexedcolumn)to(a)row(s)inthetargettable
Indexesareusedtofindrecordsinatablewhenawhereclauseisused
Indexesarealsousedtojointablesinaquery,wheremultipletablesareused
UsefulcommandsinMySQL
explain select ...
show indexes for table_name
I'madeveloperforbusinesslogic!Idon'thavetounderstandwhatthe
databasedoesandIdonotcareatall!
I'madeveloperforbusinesslogic!MycodecanbemuchmoreefficientifIunderstandwhatthedatabasedoesand
howitworks!
Makedevelopersself-sufficient
Makedevelopersself-sufficient
Makedevelopersself-sufficient
SlowSingleSQLquery–tuning/indexingmightberequired
Makedevelopersself-sufficient
Takeaways• Muchtimespentindatabasedoesnotnecessarilymeandatabaseisslow!• Performancehotspots
• ToomanySQLstatements• Missingcaching• Badquerydesign• Index(mis)usage• Undersizeddatabaseserver
• Letdevelopersknowwhat’shappeninginthedatabase• TheDBAisourfriend!
[email protected]@dynatrace.comhttp://blog.dynatrace.com
DynatraceFreeTrialFreePersonalLicensehttp://bit.ly/monitoring-2016