SQL Server magas CPU használat nyomozás és megoldás

Az utóbbi hetekben szinte minden nap SQL Servert hegesztek valahol. Leírom az összes eset tanulságát, lássuk a legutóbbit.
Adott egy igen magas forgalmú SQL Server, 1000 batch/sec körüli a terhelése. A lekérdezések derekasan optimalizálva voltak a megrendelő által, másképp nem is bírta volna produkálni a szerver ezt az áteresztő képességet (de gáz ez a szó, nem egy intim betétről írok).
A lassú lekérdezések listájában volt egy gyanúsan egyszerű, de rengetegszer meghívott lekérdezés. Ez nem volt indokolt, ezért ezt most már csak egyszer hívják meg a kliensben, aztán eltárolják az eredményét. Ezt jó észben tartani, hiába 2 lapolvasásos, seekes egy kveri, ha nagyon sokszor hívják meg, le tudja ez is fogni a szervert.
Tovább nézve látszott, hogy egy olyan trigger belseje vitte el az időt, amit még én javasoltam nekik 1-2 éve. :) A trigger feladata eladásoknál módosítani a készletet, így nem kell szummákkal kiszámítani listázáskor az aktuális készletet. Denormalizált adatokat frissített. Ezzel azt lehet majd tenni, hogy a forrástábla nem minden oszlopa módosítja a készletet, így egy IF UPDATE(…)-tel le lehet majd csökkenteni a számítások számát.
A következő pont a recompile-ésönök vizsgálata volt. A legtöbb lekérdezés ad-hoc queryként ment be, a procedure cache kihasználása gyenge volt, 60% körüli. Mivel a hibajelenség a nagy CPU terhelés volt, gyanús volt, hogy a sok fordítás-tervgenerálás eszi a procikat (8 mag, 16 logikai proc 90%-on).
A lekérdezéseket megvizsgálva kiderült a gyenge cache reuse oka: a batch-ek elejére kommentek voltak írva, amelyek kliensenként egyediek voltak. Így ugyanaz az ad-hoc query sok százféle verzióban is bement a szerverre, ami így nem tudta hatékonyan cachelni.
A kommenteket kivéve a plan reuse felment 90% fölé. :)
A harmadik dolog még egy update statistics with fullscan volt. A statisztikák rendkívül fontosak az SQL Server működéséhez, aki nem hallott még róla olvasson utána, megéri. Normál esetben, nagy tábláknál csak mintavételezve frissíti a statisztikákat a szerver, érthető módon spórolva az erőforrásokkal. Viszont egyenetlen eloszlású oszlopok esetén ez rossz hisztogramokat eredményezhet, ami miatt rossz tervet fog generálni a szerver. Ezen segíthet, ha időnként futtatunk full scanes update statisticset is. Például hétvégenként. Erre van egy nagyszerű kis sql csomag, hamarosan írok róla.

Zárásként tanulságul, az SQL kommentek messze nem olyan kis ártatlan teremtések, mint gondolnánk.

Update: az elfelejtettem leírni, hogy az eredeti 90%-ról lement 50%-ra a procihasználat.

2 Responses to “SQL Server magas CPU használat nyomozás és megoldás”

  1. Dester Says:

    Eszembe nem jutott volna soha, hogy a kommentek ilyet is okozhatnak, vagy egyáltalán bárhol, bármilyen kódban ilyen terhelést. Tanulságos volt, Soci, köszi :)

  2. Peter Tari Says:

    Érdekes, valóban nem itt keresné a hibát az ember. Köszi.