Boeiend en inspirerend optreden van drie Oracle-grootheden

Real World Performance Tour
28 mrt 2014 - Toine van Beckhoven

De Real World Performance Tour, een eendaagse presentatie over Database Performance van drie Oracle-grootheden, deed op 18 februari jl. ook Nederland aan. Het rondreizende gezelschap, bestaande uit Andrew Holdsworth, Graham Wood en Tom Kyte, was neergestreken in het Chass├ętheater in Breda, op uitnodiging van de Oracle Benelux User Group en de Oracle Gebruikersclub Holland.

De Real World Performance Tour, een eendaagse presentatie over Database Performance van drie Oracle-grootheden, deed op 18 februari jl. ook Nederland aan. Het rondreizende gezelschap, bestaande uit Andrew Holdsworth, Graham Wood en Tom Kyte, was neergestreken in het Chassétheater in Breda, op uitnodiging van de  Oracle Benelux User Group en de Oracle Gebruikersclub Holland. 

 
Holdsworth is Vice President Real World Performance bij Oracle. Dat is een afdeling die zich niet richt op het behalen van de snelste TPC benchmarks in de concurrentieslag met andere databaseleveranciers, maar ervoor wil zorgen dat gebruikers het optimale rendement halen uit de functionaliteit die Oracle biedt. Ze willen stimuleren dat gebruikers de database gebruiken zoals deze bedoeld is en de juiste dingen doen op de juiste wijze. Holdsworth was min of meer de leider van de dag. Graham Wood is Architect Server Technologies bij Oracle. We kunnen hem prima omschrijven als de man achter het vroegere Statspack en de recentere AWR, ADDM en ASH. Ofwel de man achter het diagnose instrumentarium waar de Oracle database bekend om staat. Tom Kyte noemde zichzelf ‘the most Junior member of the team here’, omdat hij de minste jaren bij Oracle achter zich heeft, ook al zijn dat er al 21.n. De andere twee werken er dus nog langer. Die opmerking leidde tot veel gelach, want bijna iedereen ziet Tom Kyte als dé Oracle database expert, die elke vraag kan beantwoorden (het is ook de man achter de populaire website AskTom).

 

OBUG RWPT

 

Opvallende uitspraken

De dag werd door velen ervaren als zeer goed en inspirerend: de drie mannen waren goed op elkaar ingespeeld en gaven ons op humoristische wijze inzicht in veel voorkomende en meest prangende performance situaties. Tom Kyte ziet op AskTom een heleboel gelijksoortige vragen. Gekscherend zei hij dat het antwoord op de helft daarvan is: 'Use bind variables!'. Veel problemen doen zich voor met applicaties die de database niet gebruiken waar ie voor bedoeld is en vooral waar ie goed in is. En veel moderne applicaties en trends zijn juist erg onvriendelijk voor de database. De sterkte van de hele dag zat voornamelijk in het feit dat ze ons niet alleen vertelden dat een bepaalde aanpak juist of onjuist is, maar dat ze dit elke keer kant en klaar aantoonden met demonstraties. Het effect van een bepaalde 'oplossing' konden ze steeds heel snel omzetten in realtime performance statistieken zoals we die kennen uit Enterprise Manager.

Een aantal van de meest opvallende uitspraken van de dag waren:

  • Wie streeft naar 'Goed is goed genoeg' heeft een probleem. Streef naar excellence (het uiterste)

  • Het is ons doel de performance van een taak/job/rapport niet met 5, 10 of zelfs 50% te verbeteren, maar 100 of 1000 maal verbetering te bereiken

  • Inserts moeten gebeuren ‘in memory’, maar zonder dat sessies elkaar beconcurreren ‘in memory’

  • Vroeger was hardware de onveranderlijke component en software juist veranderlijk. Tegenwoordig beschouwen we hardware bijna als ‘software’ en software als ‘hardware’. We zijn bang voor code changes en zoeken oplossingen in hardware of instellingen

  • 'Ieder krijgt wat ie verdient': als je de applicatie niet op de juiste wijze maakt of een verkeerd geschreven applicatie koopt, dan krijg je de slechte performance die je verdient

  • Het doel voor SQL: elk SQL statement moet ‘hint’-vrij geschreven worden

  • RAC (Real Application Clusters) laten schalen behoeft applicatie design: dat alles load balanced moet zijn is een verkeerde gedachte want load balancing schaalt niet! Het door velen in de middleware wereld verguisde ‘affinity’ bleek overduidelijk beter om een applicatie te schalen.

  • Verreweg de meeste performancewinst behaal je met code changes, niet door acties van een DBA, niet door architectuur of extra hardware.

     

Concurrency

De dag bestond uit vier grote blokken en in elk van die blokken werd uitgebreid aandacht besteed aan min of meer één probleem. De dag startte in het eerste blok met de hoofdoorzaak van wachttijden in de database: ‘concurrency’ (meerdere database sessies die dezelfde resources nodig hebben). In dit deel werden onderwerpen behandeld als record-voor-record processing (row-by-row of ook wel ‘slow-by-slow’ genoemd), versus array processing, versus zelfgemaakt parallellisme, versus set-gebaseerde DML. In blok drie ('OLTP beginselen') werd ook nog aangetoond wat het (negatieve) effect is van middleware die is opgezet met dynamische en/of te grote connection pools. De trend en de algemene gedachte is dat connection pools dynamisch moeten kunnen groeien zodra de load op de applicatieserver toeneemt. En zodra de database er langer over doet om resultaat terug te geven gaat een dynamische connection pool nog meer connecties openen om het werk te verdelen over verschillende sessies. Maar de server en de database hebben dan vooral te maken met de overhead van process management.

In extreme zin is het beter om één of slechts enkele connecties te hebben die al het werk doen en de middleware te laten doen waar ze voor bedoeld is: queuen van transacties. Eén enkele Oracle databaseconnectie kan meer werk doen dan honderden parallelle databaseconnecties, tenminste als het werk allemaal van dezelfde aard is. En zodra indexen worden toegevoegd aan tabellen waaraan de sessies allemaal records proberen toe te voegen, wordt het hebben van meerdere threads/sessies nog verergerd: wachttijden lopen harder op door contentie voor de buffer cache. Een hele wijze les konden we ook trekken uit oplossingen die in eerste instantie lijken te helpen, maar tegen gaan werken als het volume van data groeit. Reverse key indexes lijken een prachtige oplossing op een relatief lege tabel, maar in een volle tabel vullen ze de buffer cache des te harder en worden memory reads weer physical (disk) reads, en we weten hoeveel langzamer disk reads zijn dan memory reads.

In de voorbeeld applicatie was de oplossing meervoudig: zorg door een applicatie change dat de ‘key’ dusdanig wordt samengesteld dat meerdere sessies niet in dezelfde blokken schrijven. Zorg verder voor een stabiele (niet dynamische) connection pool die niet groter is dan het aantal cores van de CPU’s in je systeem (want als je 16 cores hebt, dan kunnen er maar 16 sessies tegelijkertijd ‘actief’ zijn, de rest wacht op CPU). Een grotere connectie pool heeft geen groter nut en werkt zelfs tegen. En als je wilt schalen door inzet van RAC, zorg dan dat cluster waits geen rol gaan spelen door gebruik te maken van affinity (zorg dat sessies die op de ene node zitten zo min mogelijk data en blokken delen met sessies in de andere nodes, zorg door dedicated services dat sessies op dezelfde node blijven).

 

OBUG RWPT

 

Ook een belangrijke tip die in het blok over OLTP werd meegegeven, was het gebruik van Database Resource Manager en instance caging: zorg voor reserve in je systeem en wijs niet alle CPU’s toe aan de database(s) op het systeem. Als het misgaat met een applicatie en het systeem loopt vol, dan loop je zonder die reservecapaciteit de kans dat er niets anders opzit dan het systeem te rebooten zonder dat je ook maar kans gehad hebt om een diagnose te stellen of een oplossing te implementeren. Tom Kyte noemde dit ‘The Walk of Shame’: de wandeling naar de powerknop zonder te kunnen vertellen wat er misging. Veel voorkomende oorzaken van een systeem dat op zijn knieën gaat zijn de genoemde dynamische connectie pools die teveel sessies openen, SQL cursor leaks en session leaks. Middleware programmeerfouten (Java/.Net) omtrent connection en cursor management kunnen dit veroorzaken.

 

SQL

Het tweede blok draaide geheel om SQL performance. Trage SQL statements zijn niet alleen één van de hoofdredenen voor slechte performance, het is voor heel veel mensen ook nog eens heel moeilijk te onderzoeken waarom ze traag lopen of om een executieplan te verklaren en de ‘root cause’ van het probleem te vinden. Zoals de meesten wel weten staat of valt de executiesnelheid van een SQL statement op data van normale omvang met het vermogen van de query optimizer om het beste executieplan op te stellen. En die optimizer is voor zijn rekenwerk voor het grootste deel afhankelijk van objectstatistieken en optimizer-parameters.

Er werd aangetoond dat een traag statement soms om voor de gebruiker onduidelijke reden sneller wordt door het veranderen van het statement (filter erbij of eraf, of parallel query, of een hint) en dat heel vaak maar wat wordt geprobeerd totdat het statement acceptabel snel wordt. Als dan niet uitgelegd kan worden waarom de query door die aanpassing sneller werd is het niet goed. De optimizer rekent in elke stap van het executieplan met cardinaliteit: hoeveel records verwacht het te moeten verwerken in een stap? Afhankelijk van die berekende cardinaliteiten besluit het tot een Full table scan versus een Index scan, of een nested loops join versus een Hash join, of een  parallel query broadcast versus een hash distributie. Die cardinaliteit wordt berekend aan de hand van statistieken (tabel/index/kolom/partitie/systeem).

Wat nu als de statistieken geen juist beeld geven van de data? Dan kan één cardinaliteitfout al een slecht executieplan opleveren. Maar wat zijn juiste statistieken? Ze moeten bij benadering nauwkeurig zijn. Ze hoeven niet perfect te zijn. Maar default statistieken in de database zijn in voorkomende situaties onvoldoende. Standaard worden op individuele kolommen statistieken berekend, eventueel met histogrammen (welke alleen default worden aangemaakt nadat Oracle kennis heeft gemaakt met de statements die de applicaties uitvoeren en geleerd heeft welke kolommen worden gebruikt in predicaten en met welke operators).

Het bestaan van correlatie in data tussen kolommen is een reden om naast default statistieken ook extended statistics aan te maken: deze maken correlatie inzichtelijk (iets dat dynamic sampling en SQL profiles ook doen overigens). Met die informatie kan Oracle bepalen wat de cardinaliteit zal zijn van een combinatie van filters en komt tot een veel beter executieplan. In dit deel was de belangrijkste boodschap dat we moeten begrijpen waar in het executieplan Oracle een miscalculatie maakt. Je kunt dit doen door ‘tuning by cardinality feedback’: SQL Monitor, maar ook de hint ‘gather_plan_statistics’ tonen aan wat Oracle verwacht versus wat de werkelijke cardinaliteit was in een stap: zoek naar grote afwijkingen en krijg daarmee informatie over het deelgebied waar de oplossing gezocht moet worden.

OBUG RWPT

Afsluiting

Iedereen die ik gesproken heb zei hetzelfde: een dag met goede onderwerpen, duidelijke demo’s en geheel goed verzorgd (de koffiepauzes en goed verzorgde lunch niet te vergeten). Voor velen zullen ogen geopend zijn en nieuwe argumenten gevonden zijn om weerstand te bieden tegen collega’s die beweren dat de wijze waarop zij een architectuur en applicatie design in elkaar hebben gezet de juiste is, omdat het nu eenmaal zo hoort. De verschillende demo’s die we tijdens de Real World Performance Tour hebben gezien toonden aan dat veel van wat we tegenwoordig doen, niet juist is en al zeker niet omdat het in de mode is. SOA en webservices zijn niet heilig, Connection pools moeten met zorg ingesteld worden, Load balancing is niet per definitie het beste voor schaalbaarheid, affinity is niet slecht. Maar bovenal: code change kan vele performance problemen wegnemen, is goedkoper dan nieuwe hardware en maakt verschillen die vele malen groter zijn dan wat een DBA of systeemarchitect kan doen!

Nog een link naar een video van Andrew Holdsworth tot besluit: 'OLTP Performance - Concurrent Mid-Tier Connections' (http://www.youtube.com/watch?v=xNDnVOCdvQ0).

Klik hier voor de slides van de Real World Performance Tour.

 

 

Toine van Beckhoven (http://www.jom-it.nl/) is zelfstandig en allround Oracle specialist. Oracle Performance Tuning en PL/SQL hebben zijn grootste interesse.