<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Anil Joseph Edward</title>
    <description>The latest articles on DEV Community by Anil Joseph Edward (@edwardaniljoseph).</description>
    <link>https://dev.to/edwardaniljoseph</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1772339%2F7b3d7bb3-b29b-448c-ba64-7d58416b8065.jpg</url>
      <title>DEV Community: Anil Joseph Edward</title>
      <link>https://dev.to/edwardaniljoseph</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/edwardaniljoseph"/>
    <language>en</language>
    <item>
      <title>StringBuilder is (almost always) better than String Concatenation</title>
      <dc:creator>Anil Joseph Edward</dc:creator>
      <pubDate>Mon, 16 Jun 2025 02:10:31 +0000</pubDate>
      <link>https://dev.to/edwardaniljoseph/stringbuilder-is-almost-always-better-than-string-concatenation-6f9</link>
      <guid>https://dev.to/edwardaniljoseph/stringbuilder-is-almost-always-better-than-string-concatenation-6f9</guid>
      <description>&lt;p&gt;Today we're diving into a super-cool trick to make your C# code run like lightning ⚡️ when you're working with strings. It's all about choosing the right tool for the job, and that tool is called... StringBuilder! ️&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here's the scoop:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;String Concatenation: The Usual Way&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;You know how you normally put strings together with the + sign? Like "Hello" + " " + "World"?&lt;/li&gt;
&lt;li&gt;That's called string concatenation, and while it's easy to do, it can get a bit slow when you're working with lots of strings. Imagine building a huge sentence word by word—it takes time to glue everything together!
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;WithConcatenation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;AllStrings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;finalString&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;AllStrings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;finalString&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;StringBuilder: The Performance Powerhouse&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Enter StringBuilder! It's like having a special string workshop where you can quickly assemble strings without all the fuss.&lt;/li&gt;
&lt;li&gt;Instead of creating new strings every time you add something (like with the + sign), StringBuilder lets you build the string in memory first. It's like having all your words ready to go before you start gluing.&lt;/li&gt;
&lt;li&gt;When you're done, you just ask StringBuilder for the final string, and it hands it over, perfectly crafted and ready to use!
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;WithStringBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;AllStrings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;StringBuilder&lt;/span&gt; &lt;span class="n"&gt;sb&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;StringBuilder&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;AllStrings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;sb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;finalString&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;When to Use Which:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Just a few strings?&lt;/strong&gt; The + sign is still your pal. It's quick and easy for small jobs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Building a string empire?&lt;/strong&gt; Summon the StringBuilder! It's a master of efficiency for larger string projects.

&lt;ul&gt;
&lt;li&gt;Think of it like this: if you're making a sandwich, using a knife to spread peanut butter is fine. But if you're catering a party, you'll want a big old spatula to get the job done quickly!&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key Takeaways:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;StringBuilder is almost always faster than string concatenation when you're working with more than a handful of strings.&lt;/li&gt;
&lt;li&gt;It can make your code run up to 7000 times faster in some cases!&lt;/li&gt;
&lt;li&gt;Remember to use the right tool for the job: StringBuilder for big string projects, + sign for smaller tasks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now go forth and build those strings with lightning speed! ⚡️&lt;/p&gt;

&lt;p&gt;Original Source: &lt;a href="https://www.code4it.dev/blog/top-6-string-performance-tips/#tip-1-stringbuilder-is-almost-always-better-than-string-concatenation" rel="noopener noreferrer"&gt;Tip #1: StringBuilder is (almost always) better than String Concatenation&lt;/a&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>aspdotnet</category>
    </item>
    <item>
      <title>PowerShell script to add IP ranges in bulk</title>
      <dc:creator>Anil Joseph Edward</dc:creator>
      <pubDate>Mon, 16 Jun 2025 02:09:13 +0000</pubDate>
      <link>https://dev.to/edwardaniljoseph/powershell-script-to-add-ip-ranges-in-bulk-57lf</link>
      <guid>https://dev.to/edwardaniljoseph/powershell-script-to-add-ip-ranges-in-bulk-57lf</guid>
      <description>&lt;p&gt;We had several websites hosted on a Windows server and usually there were several attempts to hack those websites using SQL Injection.&lt;br&gt;
I needed a script to add IP addresses in bulk to a Firewall rule in Windows server.&lt;/p&gt;
&lt;h2&gt;
  
  
  Custom 500 error page
&lt;/h2&gt;

&lt;p&gt;We have configured the web.config to show a custom 500 error page instead of the default one.&lt;br&gt;
And in that custom 500 page, we have a script to log those errors and send us an email when that error occurs.&lt;br&gt;
We use this for debugging or fixing issues with the application that we run.&lt;/p&gt;

&lt;p&gt;This is the code in web.config file for allowing custom error pages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;httpErrors&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;remove&lt;/span&gt; &lt;span class="na"&gt;statusCode=&lt;/span&gt;&lt;span class="s"&gt;"500"&lt;/span&gt; &lt;span class="na"&gt;subStatusCode=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;error&lt;/span&gt; &lt;span class="na"&gt;statusCode=&lt;/span&gt;&lt;span class="s"&gt;"500"&lt;/span&gt; &lt;span class="na"&gt;subStatusCode=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;path=&lt;/span&gt;&lt;span class="s"&gt;"/iishelp/common/500-100.asp"&lt;/span&gt; &lt;span class="na"&gt;responseMode=&lt;/span&gt;&lt;span class="s"&gt;"ExecuteURL"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/httpErrors&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And in our "500-100.asp" (custom error page) we had the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vb"&gt;&lt;code&gt;&lt;span class="n"&gt;strMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"HTTP Referrer : "&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ServerVariables&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"HTTP_REFERER"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;vbCrLf&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;
            &lt;span class="s"&gt;"URL : "&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ServerVariables&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"URL"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;vbCrLf&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;
            &lt;span class="s"&gt;"IP Address: "&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ServerVariables&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"REMOTE_ADDR"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;vbCrLf&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;
            &lt;span class="s"&gt;"Browser: "&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ServerVariables&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"HTTP_USER_AGENT"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;vbCrLf&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;
            &lt;span class="s"&gt;"Category: "&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;objASPError&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Category&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;vbCrLf&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;
            &lt;span class="s"&gt;"Filename: "&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;objASPError&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;vbCrLf&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;
            &lt;span class="s"&gt;"ASP Code: "&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;objASPError&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ASPCode&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;vbCrLf&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;
            &lt;span class="s"&gt;"Error Number: "&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;objASPError&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Number&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;vbCrLf&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;
            &lt;span class="s"&gt;"Source: "&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;objASPError&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Source&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;vbCrLf&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;
            &lt;span class="s"&gt;"Line Number: "&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;objASPError&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Line&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;vbCrLf&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;
            &lt;span class="s"&gt;"Column: "&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;objASPError&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;vbCrLf&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;
            &lt;span class="s"&gt;"Description: "&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;objASPError&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Description&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;vbCrLf&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;
            &lt;span class="s"&gt;"ASP Description: "&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;objASPError&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ASPDescription&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;vbCrLf&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;
            &lt;span class="s"&gt;"All HTTP: "&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ServerVariables&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ALL_HTTP"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;vbCrLf&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;
            &lt;span class="s"&gt;"POST Fields: "&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Form&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;vbCrLf&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;
            &lt;span class="s"&gt;"GET Fields: "&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QueryString&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;vbCrLf&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This message is sent as an email and also logged in Error Log Table.&lt;br&gt;
Using the IP Address information from the error message, we wanted to block the IP Address range whenever we find some kind of hacking attempt on the website.&lt;/p&gt;
&lt;h2&gt;
  
  
  PowerShell Script
&lt;/h2&gt;

&lt;p&gt;We were adding the IP address range manually in the Firewall rule.&lt;br&gt;
For example, if the IP Address was "157.55.39.12", we will add the whole range, "157.55.39.0/24" in the blocking Firewall rule.&lt;/p&gt;

&lt;p&gt;But this was cumbersome to do it manually.&lt;br&gt;
So, we used this PowerShell script for adding the IP address range to the Firewall rule, automatically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="kr"&gt;param&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Parameter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Mandatory&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;$true&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nv"&gt;$FirewallRuleName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Parameter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Mandatory&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;$true&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nv"&gt;$NewIPs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nv"&gt;$firewallRule&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Get-NetFirewallRule&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$FirewallRuleName&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nv"&gt;$existingRemoteAddresses&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Get-NetFirewallAddressFilter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-AssociatedNetFirewallRule&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$firewallRule&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RemoteAddress&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# Convert the existing remote addresses and new IP addresses to arrays&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$existingRemoteAddressesArray&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$existingRemoteAddresses&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-split&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;","&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nv"&gt;$updatedRemoteAddresses&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$existingRemoteAddressesArray&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$NewIPs&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# Remove any leading or trailing spaces from the IP addresses&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$updatedRemoteAddresses&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$updatedRemoteAddresses&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;Set-NetFirewallRule&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$FirewallRuleName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-RemoteAddress&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$updatedRemoteAddresses&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Confirm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="bp"&gt;$false&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;#Write-Output $updatedRemoteAddresses&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It was stored in a folder, "C:\PowerShellScripts"&lt;br&gt;
The code was called in PowerShell as the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;C:\PowerShellScripts&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;\AddFirewall.ps1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-FirewallRuleName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Block Other Server IP Addresses"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-NewIPs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"157.55.39.0/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"5.255.231.0/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"213.180.203.0/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"207.46.13.0/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"114.119.159.0/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"114.119.133.0/24"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this option we were able to add lots of IP address ranges to the Firewall rule to block offending IP Addresses.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Statistics and the Ascending Key Problem</title>
      <dc:creator>Anil Joseph Edward</dc:creator>
      <pubDate>Mon, 16 Jun 2025 02:08:23 +0000</pubDate>
      <link>https://dev.to/edwardaniljoseph/statistics-and-the-ascending-key-problem-466h</link>
      <guid>https://dev.to/edwardaniljoseph/statistics-and-the-ascending-key-problem-466h</guid>
      <description>&lt;p&gt;This article examines the Ascending Key Problem, which can affect query performance due to outdated statistics, and provides ways to mitigate it through SQL Server. Solutions discussed include updating statistics more regularly than the built-in thresholds, and using Traceflag 2371 to reduce the threshold for statistics updates.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://matthewmcgiffen.com/2023/07/21/statistics-and-the-ascending-key-problem-3/" rel="noopener noreferrer"&gt;Visit the link&lt;/a&gt; to read more clearly about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary:
&lt;/h2&gt;

&lt;p&gt;This article looks at the Ascending Key Problem, which can cause problems in query performance due to outdated statistics, and provides mitigations to deal with it in SQL Server.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key takeaways:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;The Ascending Key Problem relates to the most recently inserted data in a table, which may not have been sampled and included in the statistics histograms.&lt;/li&gt;
&lt;li&gt;The Optimizer will guess that there are zero rows if the range you are looking for falls beyond the top of the histogram captured in the statistics object.&lt;/li&gt;
&lt;li&gt;Scans aren't always bad for performance, as they can bail out once they are satisfied.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Counter arguments:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Updating statistics more regularly than the built-in automatic thresholds may not be necessary.&lt;/li&gt;
&lt;li&gt;Traceflag 2371 reduces the threshold for statistics updates.&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>How to delete large records in batches</title>
      <dc:creator>Anil Joseph Edward</dc:creator>
      <pubDate>Mon, 16 Jun 2025 02:07:39 +0000</pubDate>
      <link>https://dev.to/edwardaniljoseph/how-to-delete-large-records-in-batches-1c08</link>
      <guid>https://dev.to/edwardaniljoseph/how-to-delete-large-records-in-batches-1c08</guid>
      <description>&lt;p&gt;When performing long-running modifications, I'm sure many of you enjoy using batches to increase concurrency. But I want to talk about a pitfall to be aware of. If you're not careful, the method you use to implement batching can actually worsen concurrency.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Why Use Batches?
&lt;/h2&gt;

&lt;p&gt;Even without an explicit transaction, all SQL statements are atomic – changes are all or nothing. So when you have long-running modifications to make, locks on data can be held for the duration of your query and that can be too long. Especially if your changes are intended for live databases. &lt;/p&gt;

&lt;p&gt;But you can make your modifications in several smaller chunks or batches. The hope is that each individual batch executes quickly and holds locks on resources for a short period of time. But care is needed. &lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;I'm going to give an example to show what I mean. &lt;/p&gt;

&lt;p&gt;The example uses the &lt;strong&gt;FactOnlineSales&lt;/strong&gt; table in the &lt;strong&gt;ContosoRetailDW&lt;/strong&gt; database (&lt;a href="http://www.microsoft.com/en-ca/download/details.aspx?id=18279" rel="noopener noreferrer"&gt;available as a download here&lt;/a&gt;). &lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;FactOnlineSales&lt;/strong&gt; table has&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  one clustered index on &lt;strong&gt;OnlineSalesKey&lt;/strong&gt; and no other indexes,&lt;/li&gt;
&lt;li&gt;  12 million rows,&lt;/li&gt;
&lt;li&gt;  and 46 thousand database pages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Metrics to Use&lt;/strong&gt; &lt;br&gt;
In this example, I want to know how long each query takes because this should let me know roughly how long locks are held. But instead of duration, I'm going to measure logical reads. It's a little more consistent and in the examples below, it's nicely correlated with duration.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;
&lt;h2&gt;
  
  
  The Straight Query
&lt;/h2&gt;

&lt;p&gt;Suppose we want to remove sales data from &lt;strong&gt;FactOnlineSales&lt;/strong&gt; for the "Worcester Company" whose &lt;strong&gt;CustomerKey = 19036&lt;/strong&gt;. That's a simple delete statement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;DELETE&lt;/span&gt; &lt;span class="n"&gt;FactOnlineSales&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;CustomerKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;19036&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This delete statement runs an unacceptably long time. It scans the clustered index and performs 46,650 logical reads and I'm worried about concurrency issues.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  Naive Batching
&lt;/h3&gt;

&lt;p&gt;So I try to delete 1,000 rows at a time. This implementation seems reasonable on the surface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;DECLARE&lt;/span&gt; 
  &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;RC&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;WHILE&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;RC&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;

  &lt;span class="k"&gt;DELETE&lt;/span&gt; &lt;span class="n"&gt;TOP&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;FactOnlineSales&lt;/span&gt;
  &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;CustomerKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;19036&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;RC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;@@&lt;/span&gt;&lt;span class="n"&gt;ROWCOUNT&lt;/span&gt;

&lt;span class="k"&gt;END&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unfortunately, this method does poorly. &lt;br&gt;
It scans the clustered index in order to find 1,000 rows to delete. The first few batches complete quickly, but later batches gradually get slower as it takes longer and longer to scan the index to find rows to delete. &lt;/p&gt;

&lt;p&gt;By the time the script gets to the last batch, SQL Server has to delete rows near the very end of the clustered index and to find them, SQL Server has to scan the entire table. In fact, this last batch performs 46,521 logical reads (just 100 fewer reads than the straight delete). &lt;/p&gt;

&lt;p&gt;And the entire script performed 1,486,285 logical reads in total. If concurrency is what I’m after, this script is actually worse than the simple DELETE statement.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;
&lt;h3&gt;
  
  
  Careful Batching
&lt;/h3&gt;

&lt;p&gt;But I know something about the indexes on this table. I can make use of this knowledge by keeping track of my progress through the clustered index so that I can continue where I left off:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;DECLARE&lt;/span&gt;
  &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;LargestKeyProcessed&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;NextBatchMax&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;RC&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;WHILE&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;RC&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;

  &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;TOP&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;NextBatchMax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;OnlineSalesKey&lt;/span&gt;
  &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;FactOnlineSales&lt;/span&gt;
  &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;OnlineSalesKey&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;LargestKeyProcessed&lt;/span&gt;
    &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;CustomerKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;19036&lt;/span&gt;
  &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;OnlineSalesKey&lt;/span&gt; &lt;span class="k"&gt;ASC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;DELETE&lt;/span&gt; &lt;span class="n"&gt;FactOnlineSales&lt;/span&gt;
  &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;CustomerKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;19036&lt;/span&gt;
    &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;OnlineSalesKey&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;LargestKeyProcessed&lt;/span&gt;
    &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;OnlineSalesKey&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;NextBatchMax&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;RC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;@@&lt;/span&gt;&lt;span class="n"&gt;ROWCOUNT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;LargestKeyProcessed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;NextBatchMax&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;END&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The delete statements in this script performed 46,796 logical reads in total but no individual delete statement performed more than 6,363. Graphically that looks like: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ux9ijhjuy3s0anq35xi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ux9ijhjuy3s0anq35xi.png" title="Logical Reads Per Delete" alt="Logical Reads Per Delete" width="800" height="440"&gt;&lt;/a&gt;&lt;em&gt;Logical Reads Per Delete&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The careful batching method runs in roughly the same time as the straight delete statement but ensures that locks are not held for long. &lt;/p&gt;

&lt;p&gt;The naive batching method runs with an order of n² complexity (compared to the expected complexity of n) and can hold locks just as long as the straight delete statement. This underlines the importance of testing for performance. &lt;/p&gt;

&lt;p&gt;Original Source: &lt;a href="http://michaeljswart.com/2014/09/take-care-when-scripting-batches/" rel="noopener noreferrer"&gt;http://michaeljswart.com/2014/09/take-care-when-scripting-batches/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>sqlserver</category>
      <category>programming</category>
    </item>
    <item>
      <title>WordPress plugin updates shows -1</title>
      <dc:creator>Anil Joseph Edward</dc:creator>
      <pubDate>Mon, 16 Jun 2025 02:03:40 +0000</pubDate>
      <link>https://dev.to/edwardaniljoseph/wordpress-plugin-updates-shows-1-do0</link>
      <guid>https://dev.to/edwardaniljoseph/wordpress-plugin-updates-shows-1-do0</guid>
      <description>&lt;h2&gt;
  
  
  Problem
&lt;/h2&gt;

&lt;p&gt;We had an issue with a WordPress website, which wouldn't allow us to update or install any plugins.&lt;br&gt;
When we try updating a plugin, the page would show just "&lt;strong&gt;-1&lt;/strong&gt;".&lt;/p&gt;

&lt;p&gt;Even adding a new plugin would show a "-1" error.&lt;br&gt;
There wouldn't be any error messages or clue on what went wrong.&lt;br&gt;
Even enabling debugging the WordPress site did not provide any clue on what caused this issue.&lt;/p&gt;

&lt;p&gt;If you check the developer console of the browser, it would show that the "&lt;strong&gt;wp-admin/admin-ajax.php&lt;/strong&gt;" throws a "&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/403" rel="noopener noreferrer"&gt;403 error&lt;/a&gt;".&lt;/p&gt;

&lt;p&gt;And the problem is that WordPress would create a ".maintenance" file when you update the plugin. Now the site would go to Maintenance mode and will not be available, unless you manually delete the ".maintenance" file via FTP.&lt;/p&gt;

&lt;h2&gt;
  
  
  Details
&lt;/h2&gt;

&lt;p&gt;The WordPress website had many plugins. And it had the following plugins installed in it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Autoptimize&lt;/li&gt;
&lt;li&gt;Elementor&lt;/li&gt;
&lt;li&gt;Page Builder by SiteOrigin&lt;/li&gt;
&lt;li&gt;Really Simple SSL&lt;/li&gt;
&lt;li&gt;Starter Templates (from Astra)&lt;/li&gt;
&lt;li&gt;Sucuri Security - Auditing, Malware Scanner and Hardening&lt;/li&gt;
&lt;li&gt;Super Page Cache for Cloudflare&lt;/li&gt;
&lt;li&gt;Wordfence Security&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the domain was using Cloudflare to make the site load faster and use the security feature provided by it.&lt;/p&gt;

&lt;p&gt;The site was hosted in Ionos Web hosting package.&lt;/p&gt;

&lt;h2&gt;
  
  
  Steps that did NOT work
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Tried to find out the issue by bypassing Cloudflare. It did not work.&lt;/li&gt;
&lt;li&gt;Tried to stop the caching on the site and Cloudflare. It did not solve the problem.&lt;/li&gt;
&lt;li&gt;Tried deactivating the security plugins. It did not solve the problem.&lt;/li&gt;
&lt;li&gt;Tried removing "Really Simple SSL" plugin security options. Still the problem persisted.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;We were on the verge of moving the site to another hosting provider, as we could not find the source of this issue. And the hosting support could not find anything wrong with their servers or system.&lt;/p&gt;

&lt;p&gt;And then finally, I came upon this solution on WordPress support forum.&lt;br&gt;
&lt;a href="https://wordpress.org/support/topic/plugin-updates-shows-1/" rel="noopener noreferrer"&gt;https://wordpress.org/support/topic/plugin-updates-shows-1/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It stated that the issue is with &lt;strong&gt;&lt;a href="https://wpastra.com/starter-templates/" rel="noopener noreferrer"&gt;Starter Templates&lt;/a&gt;&lt;/strong&gt; (from Astra).&lt;br&gt;
I just deactivated that plugin and the updates of other plugins worked smoothly.&lt;br&gt;
And later on, I updated the &lt;strong&gt;Starter Templates&lt;/strong&gt; plugin to the latest version.&lt;br&gt;
If you face this kind of issue in the future, please check if you have installed &lt;strong&gt;Starter Templates&lt;/strong&gt;. Just deactivate it and work on the other updates.&lt;/p&gt;

</description>
      <category>wordpress</category>
    </item>
  </channel>
</rss>
