{"id":4425,"date":"2026-05-04T14:34:10","date_gmt":"2026-05-04T11:34:10","guid":{"rendered":"https:\/\/www.ozgurguler.net\/blog\/?p=4425"},"modified":"2026-05-04T14:50:36","modified_gmt":"2026-05-04T11:50:36","slug":"performansin-gercek-dinamikleri","status":"publish","type":"post","link":"https:\/\/www.ozgurguler.net\/blog\/performansin-gercek-dinamikleri\/","title":{"rendered":"Performans\u0131n Ger\u00e7ek Dinamikleri"},"content":{"rendered":"<p><strong>SQL Batch \u0130\u015fleme ve Yaz\u0131l\u0131m Taraf\u0131nda Thread Kullan\u0131m\u0131: Performans\u0131n Ger\u00e7ek Dinamikleri<\/strong><\/p>\n<p>\ud83d\udccc <strong>Giri\u015f<\/strong><br \/>\nB\u00fcy\u00fck veriyle \u00e7al\u0131\u015fan sistemlerde performans, yaln\u0131zca g\u00fc\u00e7l\u00fc donan\u0131m ile de\u011fil, do\u011fru i\u015fleme y\u00f6ntemleriyle elde edilir. Bu noktada iki temel yakla\u015f\u0131m \u00f6ne \u00e7\u0131kar:<\/p>\n<p>SQL taraf\u0131nda set-based (batch) i\u015flemler<br \/>\nYaz\u0131l\u0131m taraf\u0131nda thread (\u00e7oklu i\u015f par\u00e7ac\u0131\u011f\u0131) kullan\u0131m\u0131<\/p>\n<p>Bu makalede, bu iki yakla\u015f\u0131m\u0131n farklar\u0131n\u0131, avantajlar\u0131n\u0131, dezavantajlar\u0131n\u0131 ve ger\u00e7ek\u00e7i kullan\u0131m senaryolar\u0131n\u0131 \u00f6rneklerle inceleyece\u011fiz.<\/p>\n<p>\ud83e\udde0<strong> 1. SQL\u2019de Batch \u0130\u015fleme Nedir?<\/strong><br \/>\nKonuyu basit bir benzetmeyle a\u00e7\u0131klayal\u0131m:<\/p>\n<p>Tek tek i\u015flem (Row-by-Row): Markette her \u00fcr\u00fcn\u00fc tek tek kasaya ta\u015f\u0131mak.<br \/>\nBatch i\u015flem: T\u00fcm \u00fcr\u00fcnleri bir arabaya y\u00fckleyip tek seferde kasaya g\u00f6t\u00fcrmek.<\/p>\n<p>SQL d\u00fcnyas\u0131nda batch i\u015flem, \u00e7ok say\u0131da sat\u0131r\u0131 tek bir komutla i\u015flemektir.<\/p>\n<p>\u26a1 <strong>Performans Kar\u015f\u0131la\u015ft\u0131rmas\u0131 (100.000 kay\u0131t \u00fczerinde test)<\/strong><\/p>\n<p>\u0130\u015flem Tipi S\u00fcre A\u00e7\u0131klama<br \/>\nFOR d\u00f6ng\u00fcs\u00fc (tek tek) 1.36 sn 100.000 kez DB\u2019ye gidip gelir<br \/>\nINSERT INTO SELECT 0.04 sn Tek komutla t\u00fcm veriyi i\u015fler<br \/>\nFORALL (PL\/SQL) 0.03 sn Batch + optimize edilmi\u015f yap\u0131<\/p>\n<p>Sonu\u00e7: Batch i\u015flemler, row-by-row yakla\u015f\u0131ma g\u00f6re 20-40 kat aras\u0131nda h\u0131z art\u0131\u015f\u0131 sa\u011flayabilir.<\/p>\n<p>\u26a0\ufe0f <strong>Transaction ve Batch \u0130li\u015fkisi<\/strong><\/p>\n<p>B\u00fcy\u00fck batch\u2019ler b\u00fcy\u00fck transaction log, uzun s\u00fcreli lock ve y\u00fcksek rollback maliyeti yarat\u0131r.<br \/>\nBu nedenle ger\u00e7ek sistemlerde batch\u2019ler chunk\u2019lara b\u00f6l\u00fcnmeli ve kontroll\u00fc commit yap\u0131lmal\u0131d\u0131r.<\/p>\n<p>DECLARE @BatchSize INT = 10000;<br \/>\nDECLARE @LastId INT = 0;<br \/>\nDECLARE @RowsAffected INT = 1;<\/p>\n<p>WHILE @RowsAffected &gt; 0<br \/>\nBEGIN<br \/>\nBEGIN TRANSACTION;<\/p>\n<p>INSERT INTO HedefTablo (Kol1, Kol2, &#8230;)<br \/>\nSELECT TOP (@BatchSize) Kol1, Kol2, &#8230;<br \/>\nFROM BuyukTablo<br \/>\nWHERE Id &gt; @LastId<br \/>\nORDER BY Id;<\/p>\n<p>SET @RowsAffected = @@ROWCOUNT;<\/p>\n<p>IF @RowsAffected &gt; 0<br \/>\nSET @LastId = (SELECT MAX(Id) FROM HedefTablo<br \/>\nWHERE Id &gt; @LastId); &#8212; veya OUTPUT clause ile daha verimli al\u0131n<\/p>\n<p>COMMIT TRANSACTION;<\/p>\n<p>&#8212; Opsiyonel: Sistem y\u00fck\u00fcn\u00fc azaltmak i\u00e7in<br \/>\n&#8212; WAITFOR DELAY &#8217;00:00:001&#8242;;<br \/>\nEND<\/p>\n<p>\ud83e\uddf5 <strong>2. Thread Nedir ve Ne Zaman Kullan\u0131l\u0131r?<\/strong><\/p>\n<p>Thread, bir program\u0131n ayn\u0131 anda birden fazla i\u015fi y\u00fcr\u00fctebilme yetene\u011fidir.<\/p>\n<p><a href=\"https:\/\/www.ozgurguler.net\/blog\/wp-content\/uploads\/2026\/05\/Tablo1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-4428\" src=\"https:\/\/www.ozgurguler.net\/blog\/wp-content\/uploads\/2026\/05\/Tablo1.jpg\" alt=\"\" width=\"515\" height=\"83\" srcset=\"https:\/\/www.ozgurguler.net\/blog\/wp-content\/uploads\/2026\/05\/Tablo1.jpg 515w, https:\/\/www.ozgurguler.net\/blog\/wp-content\/uploads\/2026\/05\/Tablo1-300x48.jpg 300w\" sizes=\"auto, (max-width: 515px) 100vw, 515px\" \/><\/a><\/p>\n<p>Pratik Form\u00fcl:<br \/>\nOptimum Thread Say\u0131s\u0131 \u2248 \u00c7ekirdek Say\u0131s\u0131 \u00d7 (1 + Bekleme S\u00fcresi \/ \u0130\u015flem S\u00fcresi)<\/p>\n<p>CPU Bound i\u015fler i\u00e7in genellikle \u00e7ekirdek say\u0131s\u0131 (veya +1) yeterlidir.<br \/>\nI\/O Bound i\u015fler i\u00e7in 2x \u2013 4x \u00e7ekirdek say\u0131s\u0131 daha iyi sonu\u00e7 verir.<\/p>\n<p>\u26a0\ufe0f <strong>Kritik Uyar\u0131 (CPU Bound \u0130\u015fler):<\/strong><\/p>\n<p>CPU-bound i\u015flerde lineer h\u0131z art\u0131\u015f\u0131 (4 \u00e7ekirdek = 4x h\u0131z) nadiren elde edilir.<br \/>\nAmdahl Yasas\u0131, lock\u2019lar, bellek \u00e7eki\u015fmesi ve cache coherency sorunlar\u0131 nedeniyle ger\u00e7ek kazan\u00e7 genellikle s\u0131n\u0131rl\u0131d\u0131r.<\/p>\n<p>\ud83d\udcbb <strong>3. Delphi ile Batch + Thread Kullan\u0131m\u0131<\/strong><\/p>\n<p>type<br \/>\nTIslemThread = class(TThread)<br \/>\nprotected<br \/>\nprocedure Execute; override;<br \/>\nend;<\/p>\n<p>procedure TIslemThread.Execute;<br \/>\nvar<br \/>\ni: Integer;<br \/>\nbegin<br \/>\nfor i := 1 to 1000000 do<br \/>\nbegin<br \/>\n\/\/ Yo\u011fun i\u015flem \/ Batch i\u015flemi burada<\/p>\n<p>if (i mod 5000 = 0) then<br \/>\nTThread.Queue(nil,<br \/>\nprocedure<br \/>\nbegin<br \/>\nForm1.ProgressBar1.Position := Form1.ProgressBar1.Position + 5000;<br \/>\nend);<br \/>\nend;<br \/>\nend;<\/p>\n<p><strong>Modern Delphi Alternatifleri:<\/strong><\/p>\n<p>System.Threading.TParallel.For<br \/>\nTTask.Run ve ITask aray\u00fcz\u00fc<br \/>\nTThread.CreateAnonymousThread<\/p>\n<p>B\u00fcy\u00fck Dosya \u0130\u015fleme \u00d6rne\u011fi<br \/>\n1 GB log dosyas\u0131n\u0131 4 thread ile i\u015flemek ciddi h\u0131z kazand\u0131rabilir.<br \/>\nDikkat edilmesi gerekenler:<\/p>\n<p>Sat\u0131r ortas\u0131ndan b\u00f6lmemek (buffered okuma)<br \/>\nEncoding uyumu<br \/>\nDisk I\/O bottleneck (en yayg\u0131n s\u0131n\u0131rlay\u0131c\u0131 fakt\u00f6r)<\/p>\n<p>Thread G\u00fcvenli\u011fi:<br \/>\nOrtak kaynaklara eri\u015fimde TCriticalSection, TMonitor veya Producer-Consumer (Queue) modelini tercih edin. A\u015f\u0131r\u0131 lock kullan\u0131m\u0131 paralelli\u011fi \u00f6ld\u00fcr\u00fcr.<\/p>\n<p>\ud83e\udde9 <strong>4. .NET D\u00fcnyas\u0131nda Modern Yakla\u015f\u0131m<\/strong><\/p>\n<p>Parallel.ForEach (Partitioner ile daha verimli)<br \/>\nasync\/await + Task.WhenAll<br \/>\nSystem.Threading.Channels<br \/>\nTPL Dataflow<\/p>\n<p><strong>\u00d6rnek:<\/strong><br \/>\nParallel.ForEach(musteriler, new ParallelOptions { MaxDegreeOfParallelism = 8 }, musteri =&gt;<br \/>\n{<br \/>\nMailGonder(musteri);<br \/>\n});<\/p>\n<p>BackgroundWorker eski bir teknolojidir. Yeni projelerde kesinlikle Task + async\/await yakla\u015f\u0131m\u0131 \u00f6nerilir.<\/p>\n<p>\u2696\ufe0f <strong>5. SQL mi, Thread mi?<\/strong><\/p>\n<p><a href=\"https:\/\/www.ozgurguler.net\/blog\/wp-content\/uploads\/2026\/05\/Tablo2.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-4429\" src=\"https:\/\/www.ozgurguler.net\/blog\/wp-content\/uploads\/2026\/05\/Tablo2.jpg\" alt=\"\" width=\"562\" height=\"146\" srcset=\"https:\/\/www.ozgurguler.net\/blog\/wp-content\/uploads\/2026\/05\/Tablo2.jpg 562w, https:\/\/www.ozgurguler.net\/blog\/wp-content\/uploads\/2026\/05\/Tablo2-300x78.jpg 300w\" sizes=\"auto, (max-width: 562px) 100vw, 562px\" \/><\/a><\/p>\n<p>\ud83d\udd25 <strong>En Kritik Ger\u00e7ek<\/strong><\/p>\n<p>SQL motorlar\u0131 set-based i\u015flemler i\u00e7in \u00f6zel olarak optimize edilmi\u015ftir.<br \/>\nBasit ve veri yo\u011fun i\u015flemlerde SQL neredeyse her zaman kazan\u0131r.<br \/>\nKarma\u015f\u0131k i\u015f kurallar\u0131, d\u0131\u015f sistem entegrasyonlar\u0131 ve y\u00fcksek I\/O beklemelerinde ise thread\/async yakla\u015f\u0131m\u0131 devreye girer.<\/p>\n<p>\ud83e\udde0<strong> Sonu\u00e7<\/strong><\/p>\n<p>Performans optimizasyonu tek bir y\u00f6ntemle de\u011fil, do\u011fru arac\u0131 do\u011fru yerde kullanmakla elde edilir.<\/p>\n<p>SQL Batch \u2192 Veri taraf\u0131nda maksimum h\u0131z<br \/>\nThread \/ Async \u2192 Paralel i\u015f y\u00fcklerinde ve d\u0131\u015f ba\u011f\u0131ml\u0131l\u0131klarda g\u00fc\u00e7<\/p>\n<p>En iyi sonu\u00e7, bu iki yakla\u015f\u0131m\u0131n bilin\u00e7li ve dengeli \u015fekilde bir arada kullan\u0131lmas\u0131yla elde edilir.<br \/>\nDo\u011fru mimari kararlar sistemi sadece h\u0131zland\u0131rmakla kalmaz, ayn\u0131 zamanda s\u00fcrd\u00fcr\u00fclebilir ve \u00f6l\u00e7eklenebilir hale getirir.<\/p>\n<p>\ud83d\udcca <strong>Benchmark Nas\u0131l Yap\u0131l\u0131r? (Pratik \u00d6rnekler)<\/strong><\/p>\n<p>Performans iddialar\u0131n\u0131 asla tahmine b\u0131rakmay\u0131n. Her zaman \u00f6l\u00e7\u00fcn.<\/p>\n<p><strong>1. SQL taraf\u0131nda basit benchmark:<\/strong><\/p>\n<p>SET STATISTICS TIME ON;<br \/>\nSET STATISTICS IO ON;<\/p>\n<p>&#8212; Test edilecek sorgu buraya<br \/>\nINSERT INTO HedefTablo<br \/>\nSELECT &#8230; FROM BuyukTablo<br \/>\nWHERE &#8230;;<\/p>\n<p>SET STATISTICS TIME OFF;<br \/>\nSET STATISTICS IO OFF;<\/p>\n<p>SQL Server Management Studio\u2019da \u201cInclude Actual Execution Plan\u201d ile birlikte kullan\u0131n.<br \/>\nDaha profesyonel \u00f6l\u00e7\u00fcm i\u00e7in: Extended Events veya Query Store \u00f6nerilir.<\/p>\n<p><strong>2. Delphi taraf\u0131nda basit zaman \u00f6l\u00e7\u00fcm\u00fc:<\/strong><br \/>\nvar<br \/>\nSW: TStopwatch;<br \/>\nbegin<br \/>\nSW := TStopwatch.StartNew;<\/p>\n<p>\/\/ Test edilecek kod (thread&#8217;li veya threadsiz)<\/p>\n<p>SW.Stop;<br \/>\nWriteln(&#8216;Ge\u00e7en s\u00fcre: &#8216;, SW.ElapsedMilliseconds, &#8216; ms&#8217;);<br \/>\nend;<\/p>\n<p><strong>3. .NET taraf\u0131nda profesyonel benchmark<\/strong><br \/>\n\/\/ BenchmarkDotNet k\u00fct\u00fcphanesi ile (en do\u011fru y\u00f6ntem)<br \/>\n[MemoryDiagnoser]<br \/>\npublic class BatchVsThreadBenchmark<br \/>\n{<br \/>\n[Benchmark]<br \/>\npublic void SqlBatchYontemi() { \/* &#8230; *\/ }<\/p>\n<p>[Benchmark]<br \/>\npublic void ParallelThreadYontemi() { \/* &#8230; *\/ }<br \/>\n}<\/p>\n<p><strong>Alt\u0131n Kural: Hi\u00e7bir optimizasyon, ger\u00e7ek \u00fcretim verisi ve \u00fcretim benzeri y\u00fck alt\u0131nda test edilmeden kabul edilmemelidir.<\/strong><\/p>\n<p><strong>\u270d\ufe0f Son S\u00f6z<\/strong><\/p>\n<p>Bu makale, ger\u00e7ek sistemlerde kar\u015f\u0131la\u015f\u0131lan performans problemlerine pratik bir bak\u0131\u015f sunmay\u0131 ama\u00e7lamaktad\u0131r.<br \/>\nTeoriyi ara\u00e7 olarak kullan\u0131n, ama son karar\u0131 \u00f6l\u00e7\u00fcmler versin.<\/p>\n<p><strong>Yazar: \u00d6zg\u00fcr G\u00dcLER \u2013 White Eagles<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>SQL Batch \u0130\u015fleme ve Yaz\u0131l\u0131m Taraf\u0131nda Thread Kullan\u0131m\u0131: Performans\u0131n Ger\u00e7ek Dinamikleri \ud83d\udccc Giri\u015f B\u00fcy\u00fck veriyle \u00e7al\u0131\u015fan sistemlerde performans, yaln\u0131zca g\u00fc\u00e7l\u00fc donan\u0131m ile de\u011fil, do\u011fru i\u015fleme y\u00f6ntemleriyle elde edilir. Bu noktada iki temel yakla\u015f\u0131m \u00f6ne \u00e7\u0131kar: SQL taraf\u0131nda set-based (batch) i\u015flemler Yaz\u0131l\u0131m taraf\u0131nda thread (\u00e7oklu i\u015f par\u00e7ac\u0131\u011f\u0131) kullan\u0131m\u0131 Bu makalede, bu iki yakla\u015f\u0131m\u0131n farklar\u0131n\u0131, avantajlar\u0131n\u0131, dezavantajlar\u0131n\u0131 [&hellip;]<\/p>\n","protected":false},"author":4,"featured_media":4102,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[243,3],"tags":[],"class_list":["post-4425","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-one-cikan","category-bazi-biten-projeler"],"_links":{"self":[{"href":"https:\/\/www.ozgurguler.net\/blog\/wp-json\/wp\/v2\/posts\/4425","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.ozgurguler.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.ozgurguler.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.ozgurguler.net\/blog\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ozgurguler.net\/blog\/wp-json\/wp\/v2\/comments?post=4425"}],"version-history":[{"count":3,"href":"https:\/\/www.ozgurguler.net\/blog\/wp-json\/wp\/v2\/posts\/4425\/revisions"}],"predecessor-version":[{"id":4430,"href":"https:\/\/www.ozgurguler.net\/blog\/wp-json\/wp\/v2\/posts\/4425\/revisions\/4430"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.ozgurguler.net\/blog\/wp-json\/wp\/v2\/media\/4102"}],"wp:attachment":[{"href":"https:\/\/www.ozgurguler.net\/blog\/wp-json\/wp\/v2\/media?parent=4425"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.ozgurguler.net\/blog\/wp-json\/wp\/v2\/categories?post=4425"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.ozgurguler.net\/blog\/wp-json\/wp\/v2\/tags?post=4425"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}