<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="https://shazwazza.com/rss/xslt"?>
<rss xmlns:a10="http://www.w3.org/2005/Atom" version="2.0">
  <channel>
    <title>Shazwazza</title>
    <link>https://shazwazza.com/</link>
    <description>My blog which is pretty much just all about coding</description>
    <generator>Articulate, blogging built on Umbraco</generator>
    <image>
      <url>/media/0libq25y/frog.png?rmode=max&amp;v=1da0e911f4e6890</url>
      <title>Shazwazza</title>
      <link>https://shazwazza.com/</link>
    </image>
    <item>
      <guid isPermaLink="false">1329</guid>
      <link>https://shazwazza.com/post/petapoco-may-cause-high-memory-usage-with-certain-queries/</link>
      <category>ASP.Net</category>
      <category>Web Development</category>
      <title>PetaPoco may cause high memory usage with certain queries</title>
      <description>&lt;p&gt;If you are using &lt;a href="https://github.com/toptensoftware/PetaPoco" target="_blank"&gt;PetaPoco&lt;/a&gt;, or &lt;a href="https://github.com/schotime/NPoco" target="_blank"&gt;NPoco&lt;/a&gt; (&lt;em&gt;which seams to be the most up-to-date fork of the project&lt;/em&gt;), the title of this post might be a bit scary… but hopefully you won’t have to worry. This really depends on how you create your queries and how many different query structures you are executing.&lt;/p&gt;
&lt;h2&gt;High memory usage&lt;/h2&gt;
&lt;p&gt;Here is the code in relation to the memory growth when using PetaPoco:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/toptensoftware/PetaPoco/blob/master/PetaPoco/PetaPoco.cs#L1836" title="https://github.com/toptensoftware/PetaPoco/blob/master/PetaPoco/PetaPoco.cs#L1836"&gt;https://github.com/toptensoftware/PetaPoco/blob/master/PetaPoco/PetaPoco.cs#L1836&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;What is happening here is that every time a POCO needs to be mapped from a data source, this will add more values to a static cache, specifically this one:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/toptensoftware/PetaPoco/blob/master/PetaPoco/PetaPoco.cs#L2126" title="https://github.com/toptensoftware/PetaPoco/blob/master/PetaPoco/PetaPoco.cs#L2126"&gt;https://github.com/toptensoftware/PetaPoco/blob/master/PetaPoco/PetaPoco.cs#L2126&lt;/a&gt;  (&lt;em&gt;m_PocoDatas&lt;/em&gt;)&lt;/p&gt;
&lt;p&gt;This isn’t a bad thing… but it can be if you are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;using non-parameterized where clauses&lt;/li&gt;
&lt;li&gt;you have dynamically generated where clauses&lt;/li&gt;
&lt;li&gt;you use a lot of sql ‘IN’ clauses – since the items in the array being passed to the ‘IN’ clauses is dynamic&lt;/li&gt;
&lt;li&gt;you have tons of differently statically unique where clauses&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each time a unique SQL query is sent to PetaPoco it will store this SQL string and associate it to a delegate (which is also cached). Over time, as these unique SQL queries are executed, the internal static cache will grow. In some cases this could consume quite a lot of memory.&lt;/p&gt;
&lt;p&gt;The other thing to note is how large the ‘key’ that PetaPoco/NPoco uses:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;var key = &lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(&lt;span class="str"&gt;"{0}:{1}:{2}:{3}:{4}"&lt;/span&gt;, sql, connString, ForceDateTimesToUtc, firstColumn, countColumns);&lt;/pre&gt;
&lt;p&gt;Considering how many queries might be executing in your application, the storage for these keys alone could take up quite a lot of memory! An SQL statement combined with a connection string could be very long, and each of these combinations gets stored in memory for every unique SQL query executed that returns mapped POCO objects.&lt;/p&gt;
&lt;h2&gt;Parameterized queries vs. non-parameterized&lt;/h2&gt;
&lt;p&gt;Here’s some examples of why non-parameterized queries will cause lots of memory consumption. Lets say we have a simple query like:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;db.Query&amp;lt;MyTable&amp;gt;(&lt;span class="str"&gt;"WHERE MyColumn=@myValue"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; {myValue = &lt;span class="str"&gt;"test"&lt;/span&gt;})&lt;/pre&gt;
&lt;p&gt;Which results in this SQL:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;SELECT&lt;/span&gt; * &lt;span class="kwrd"&gt;FROM&lt;/span&gt; MyTable &lt;span class="kwrd"&gt;WHERE&lt;/span&gt; MyColumn = @myValue&lt;/pre&gt;
&lt;p&gt;This query can be used over and over again with a different value and PetaPoco will simply store a single SQL key in it’s internal cache. However, if you are executing queries without real parameters such as:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;db.Query&amp;lt;MyTable&amp;gt;(&lt;span class="str"&gt;"WHERE MyColumn='hello'"&lt;/span&gt;);
db.Query&amp;lt;MyTable&amp;gt;(&lt;span class="str"&gt;"WHERE MyColumn='world'"&lt;/span&gt;);
db.Query&amp;lt;MyTable&amp;gt;(&lt;span class="str"&gt;"WHERE MyColumn='hello world'"&lt;/span&gt;);&lt;/pre&gt;
&lt;p&gt;Which results in this SQL:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;SELECT&lt;/span&gt; * &lt;span class="kwrd"&gt;FROM&lt;/span&gt; MyTable &lt;span class="kwrd"&gt;WHERE&lt;/span&gt; MyColumn = &lt;span class="str"&gt;'hello'&lt;/span&gt;;
&lt;span class="kwrd"&gt;SELECT&lt;/span&gt; * &lt;span class="kwrd"&gt;FROM&lt;/span&gt; MyTable &lt;span class="kwrd"&gt;WHERE&lt;/span&gt; MyColumn = &lt;span class="str"&gt;'world'&lt;/span&gt;;
&lt;span class="kwrd"&gt;SELECT&lt;/span&gt; * &lt;span class="kwrd"&gt;FROM&lt;/span&gt; MyTable &lt;span class="kwrd"&gt;WHERE&lt;/span&gt; MyColumn = &lt;span class="str"&gt;'hello world'&lt;/span&gt;;&lt;/pre&gt;
&lt;p&gt;Then PetaPoco will store each of these statements against a delegate in it’s internal cache since each of these string statements are not equal to each other.&lt;/p&gt;
&lt;p&gt;Depending on your application you still might have a very large number of unique parameterized queries, though I’d assume you’d have to have a terrifically huge amount for it to be a worry.&lt;/p&gt;
&lt;h2&gt;Order by queries&lt;/h2&gt;
&lt;p&gt;Unfortunately even if you use parameterized queries, PetaPoco will store the SQL query key with it’s &lt;em&gt;Order By&lt;/em&gt; clause which isn’t necessary and will again mean more duplicate SQL keys and delegates being tracked. For example if you have these resulting queries:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;SELECT&lt;/span&gt; * &lt;span class="kwrd"&gt;FROM&lt;/span&gt; MyTable &lt;span class="kwrd"&gt;WHERE&lt;/span&gt; MyColumn = @myValue &lt;span class="kwrd"&gt;ORDER&lt;/span&gt; &lt;span class="kwrd"&gt;BY&lt;/span&gt; SomeField;
&lt;span class="kwrd"&gt;SELECT&lt;/span&gt; * &lt;span class="kwrd"&gt;FROM&lt;/span&gt; MyTable &lt;span class="kwrd"&gt;WHERE&lt;/span&gt; MyColumn = @myValue &lt;span class="kwrd"&gt;ORDER&lt;/span&gt; &lt;span class="kwrd"&gt;BY&lt;/span&gt; AnotherField;&lt;/pre&gt;
&lt;p&gt;PetaPoco will store each of these statements in it’s internal cache separately since the strings don’t match, however the delegate that PetaPoco is storing against these SQL statements isn’t concerned about the ordering output, it’s only concerned about the column and table selection so in theory it should be stripping off the last &lt;em&gt;Order By &lt;/em&gt;clause&lt;em&gt; (and other irrelevant clauses) &lt;/em&gt;to avoid this duplication.&lt;/p&gt;
&lt;h2&gt;A slightly better implementation&lt;/h2&gt;
&lt;p&gt;First, if you are using PetaPoco/NPoco, you shouldn’t use dynamic queries for the point’s mentioned above. If you need this functionality then I suppose it might be worth these libraries adding some sort of property on the Database object or a parameter in either the Fetch or Query methods to specify that you don’t want to use the internal cache (this will be slower, but you won’t get unwanted memory growth). I’d really just suggest not using dynamically created where clauses ;-)&lt;/p&gt;
&lt;p&gt;Next, there’s a few things that could be fixed in the PetaPoco/NPoco core to manage memory a little better:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The size the the key that is stored in memory doesn’t need to be that big. A better implementation would be to use a hash combiner class to combine the &lt;em&gt;GetHashCode&lt;/em&gt; result of each of those parameters that make up the key. This is a very fast way to create a hash of some strings that will result in a much smaller key. An example of a hash combiner class is here (which is actually inspired by the various internal hash code combiner classes in .Net): &lt;a href="https://github.com/umbraco/Umbraco-CMS/blob/7.2.0/src/Umbraco.Core/HashCodeCombiner.cs" title="https://github.com/umbraco/Umbraco-CMS/blob/7.2.0/src/Umbraco.Core/HashCodeCombiner.cs"&gt;&lt;em&gt;https://github.com/umbraco/Umbraco-CMS/blob/7.2.0/src/Umbraco.Core/HashCodeCombiner.cs&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Instead of storing all of this cache in static variables, have them stored in an &lt;em&gt;ObjectCache/MemoryCache (&lt;/em&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.caching.objectcache(v=vs.110).aspx" title="http://msdn.microsoft.com/en-us/library/system.runtime.caching.objectcache(v=vs.110).aspx"&gt;&lt;em&gt;http://msdn.microsoft.com/en-us/library/system.runtime.caching.objectcache(v=vs.110).aspx&lt;/em&gt;&lt;/a&gt;&lt;em&gt;) with &lt;/em&gt;a sliding expiration so the memory can get collected when it’s unused&lt;/li&gt;
&lt;li&gt;The Order By clause should be ignored based on the point mentioned above&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I’ve created a PR for NPoco &lt;a href="https://github.com/schotime/NPoco/pull/134" target="_blank"&gt;here&lt;/a&gt;, and also created an issue on the original PetaPoco source &lt;a href="https://github.com/toptensoftware/PetaPoco/issues/185" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Thu, 23 Mar 2023 15:08:15 Z</pubDate>
      <a10:updated>2023-03-23T15:08:15Z</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1192</guid>
      <link>https://shazwazza.com/post/umbraco-41-benchmarks-part-2-back-office-database-queries/</link>
      <category>Umbraco</category>
      <title>Umbraco 4.1 Benchmarks Part 2 (Back Office Database Queries)</title>
      <description>&lt;div class="imported-post"&gt;This post was imported from FARMCode.org which has been discontinued. These posts now exist here as an archive. They may contain broken links and images.&lt;/div&gt;This is part 2 in a series of Umbraco 4.1 benchmarks created by various members of the core team in the lead up to launch. See &lt;a href="http://farmcode.org/post/2010/04/19/Umbraco-41-Benchmarks-Part-1-%28Do-Over%29.aspx"&gt;Part 1 here&lt;/a&gt; on request/response peformance in the Umbraco back office.  &lt;p&gt;This benchmark report looks at the data layer improvements in 4.1 by comparing query counts in 4.1 to 4.0.3. Not only has the data layer improved but there’s been significant improvements in the consumption of the data layer API made by many of the 4.1 pages and controls.&lt;/p&gt; &lt;p&gt;The stats below are represented as a percentage of the total calls of 4.0.3 where the number of queries in 4.0.3 are 100% and the number of queries in 4.1 are a percentage in relation to this. These results are based on the procedures listed at the bottom of this post and on averages run over 3 separate trials.&lt;/p&gt; &lt;style&gt;


















.stats th {background-color:#ffffcc;color:black;}
.stats td, .stats th {
border-top:solid 1px black;
border-right:solid 1px black;
border-top:solid 1px black;
}
.stats td.first, .stats th.first {
border-left:solid 1px black;
}
.stats tr.bottom td, .stats td.bottom {
border-bottom:solid 1px black;
}
.stats tr.one { background-color:#ededed;}
.stats tr.two { background-color:#dcdcdc;}
.stats tr.three { background-color:#ededed;}
.stats tr.four {background-color:#d6f5f5;}&lt;/style&gt;  &lt;table class="stats" cellspacing="0" cellpadding="2" width="470"&gt; &lt;tbody&gt; &lt;tr class="one"&gt; &lt;th class="first" valign="top" width="326"&gt;Step&lt;/td&gt; &lt;/th&gt; &lt;th valign="top" width="72"&gt;4.0.3&lt;/td&gt; &lt;/th&gt; &lt;th valign="top" width="70"&gt;4.1.0&lt;/td&gt; &lt;/tr&gt;&lt;/th&gt;&lt;/tr&gt; &lt;tr class="two"&gt; &lt;td class="first" valign="top" width="326"&gt;Login&lt;/td&gt; &lt;td valign="top" width="72"&gt;100%&lt;/td&gt; &lt;td valign="top" width="70"&gt;68%&lt;/td&gt;&lt;/tr&gt; &lt;tr class="one"&gt; &lt;td class="first" valign="top" width="326"&gt;Expand all Content nodes&lt;/td&gt; &lt;td valign="top" width="72"&gt;100%&lt;/td&gt; &lt;td valign="top" width="70"&gt;23%&lt;/td&gt;&lt;/tr&gt; &lt;tr class="one"&gt; &lt;td class="first" valign="top" width="326"&gt;Edit Home node&lt;/td&gt; &lt;td valign="top" width="72"&gt;100%&lt;/td&gt; &lt;td valign="top" width="70"&gt;49%&lt;/td&gt;&lt;/tr&gt; &lt;tr class="two"&gt; &lt;td class="first" valign="top" width="326"&gt;Publishing Home node&lt;/td&gt; &lt;td valign="top" width="72"&gt;100%&lt;/td&gt; &lt;td valign="top" width="70"&gt;55%&lt;/td&gt;&lt;/tr&gt; &lt;tr class="one"&gt; &lt;td class="first" valign="top" width="326"&gt;Edit About Umbraco node&lt;/td&gt; &lt;td valign="top" width="72"&gt;100%&lt;/td&gt; &lt;td valign="top" width="70"&gt;49%&lt;/td&gt;&lt;/tr&gt; &lt;tr class="two"&gt; &lt;td class="first" valign="top" width="326"&gt;Go to Settings App&lt;/td&gt; &lt;td valign="top" width="72"&gt;100%&lt;/td&gt; &lt;td valign="top" width="70"&gt;100%&lt;/td&gt;&lt;/tr&gt; &lt;tr class="one"&gt; &lt;td class="first" valign="top" width="326"&gt;Expand Document types tree&lt;/td&gt; &lt;td valign="top" width="72"&gt;100%&lt;/td&gt; &lt;td valign="top" width="70"&gt;100%&lt;/td&gt;&lt;/tr&gt; &lt;tr class="two"&gt; &lt;td class="first" valign="top" width="326"&gt;Edit Home document type&lt;/td&gt; &lt;td valign="top" width="72"&gt;100%&lt;/td&gt; &lt;td valign="top" width="70"&gt;61%&lt;/td&gt;&lt;/tr&gt; &lt;tr class="one"&gt; &lt;td class="first" valign="top" width="326"&gt;Save Home document type&lt;/td&gt; &lt;td valign="top" width="72"&gt;100%&lt;/td&gt; &lt;td valign="top" width="70"&gt;67%&lt;/td&gt;&lt;/tr&gt; &lt;tr class="two"&gt; &lt;td class="first" valign="top" width="326"&gt;Go to Media app&lt;/td&gt; &lt;td valign="top" width="72"&gt;100%&lt;/td&gt; &lt;td valign="top" width="70"&gt;50%&lt;/td&gt;&lt;/tr&gt; &lt;tr class="one"&gt; &lt;td class="first" valign="top" width="326"&gt;Create new folder labeled ‘Test’&lt;/td&gt; &lt;td valign="top" width="72"&gt;100%&lt;/td&gt; &lt;td valign="top" width="70"&gt;88%&lt;/td&gt;&lt;/tr&gt; &lt;tr class="two"&gt; &lt;td class="first" valign="top" width="326"&gt;Create new image under new ‘Test’ folder labeled ‘test1’&lt;/td&gt; &lt;td valign="top" width="72"&gt;100%&lt;/td&gt; &lt;td valign="top" width="70"&gt;64%&lt;/td&gt;&lt;/tr&gt; &lt;tr class="one"&gt; &lt;td class="first" valign="top" width="326"&gt;Upload new image file to ‘test1’ and save the node&lt;/td&gt; &lt;td valign="top" width="72"&gt;100%&lt;/td&gt; &lt;td valign="top" width="70"&gt;49%&lt;/td&gt;&lt;/tr&gt; &lt;tr class="two"&gt; &lt;td class="first" valign="top" width="326"&gt;Go to Content app (and in the case of 4.0.3, expand the tree and select the About Umbraco node since in 4.1 this will already be selected and loaded)&lt;/td&gt; &lt;td valign="top" width="72"&gt;100%&lt;/td&gt; &lt;td valign="top" width="70"&gt;41%&lt;/td&gt;&lt;/tr&gt; &lt;tr class="one"&gt; &lt;td class="first" valign="top" width="326"&gt;Edit Home node&lt;/td&gt; &lt;td valign="top" width="72"&gt;100%&lt;/td&gt; &lt;td valign="top" width="70"&gt;43%&lt;/td&gt;&lt;/tr&gt; &lt;tr class="two"&gt; &lt;td class="first" valign="top" width="326"&gt;Add ‘test1’ image to the ‘Text’ WYSIWYG property with the image picker and Publish node&lt;/td&gt; &lt;td class="first" valign="top" width="72"&gt;100%&lt;/td&gt; &lt;td valign="top" width="70"&gt;49%&lt;/td&gt;&lt;/tr&gt; &lt;tr class="four"&gt; &lt;td class="first" valign="top" width="326"&gt;Average of averages above&lt;/td&gt; &lt;td valign="top" width="72"&gt;&amp;nbsp;&lt;/td&gt; &lt;td valign="top" width="70"&gt;60%&lt;/td&gt;&lt;/tr&gt; &lt;tr class="four bottom"&gt; &lt;td class="first" valign="top" width="326"&gt;Complete run through of the above steps&lt;/td&gt; &lt;td valign="top" width="72"&gt;100%&lt;/td&gt; &lt;td valign="top" width="70"&gt;66%&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;So based on averages, Umbraco 4.1 is looking to have around &lt;font size="4"&gt;&lt;strong&gt;40% less&lt;/strong&gt; &lt;/font&gt;queries made than 4.0.3!!! Thats HUGE! &lt;/p&gt; &lt;p&gt;The following steps were taken on each trial of the above steps:&lt;/font&gt;&lt;/em&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;New instances of both 4.0.3 and 4.1  &lt;li&gt;Install CWS package on both instances  &lt;li&gt;Log out of both instances  &lt;li&gt;Bump web.config for both instances (clear out all data cache)  &lt;li&gt;Use SQL Profiler to determine query counts for each step listed above &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Also, SQL debugging has been added to 4.1 for MS SQL instances. If you compile the source in Debug mode you can get the SQL command output by adding a trace listener to your web.config. Underneath the configuration node you can add this xml block:&lt;/p&gt;&lt;pre&gt;&amp;lt;system.diagnostics&amp;gt;
	&amp;lt;trace autoflush="true"&amp;gt;
	  &amp;lt;listeners&amp;gt;
		&amp;lt;add name="SqlListener" 
			type="System.Diagnostics.TextWriterTraceListener" 
			initializeData="trace.log" /&amp;gt;
	  &amp;lt;/listeners&amp;gt;
	&amp;lt;/trace&amp;gt;
&amp;lt;/system.diagnostics&amp;gt;
&lt;/pre&gt;
&lt;p&gt;This will create a trace.log file in the root of your web app SQL debugging.&lt;/p&gt;</description>
      <pubDate>Thu, 23 Mar 2023 15:08:14 Z</pubDate>
      <a10:updated>2023-03-23T15:08:14Z</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1286</guid>
      <link>https://shazwazza.com/post/umbraco-41-database-structure/</link>
      <category>Umbraco</category>
      <title>Umbraco 4.1 Database Structure</title>
      <description>&lt;div class="imported-post"&gt;This post was imported from FARMCode.org which has been discontinued. These posts now exist here as an archive. They may contain broken links and images.&lt;/div&gt;We’re finally shipping Umbraco 4.1 with all of the real database constraints, indexes and keys that it so much deserves! This issue was reported on over 3 years ago (&lt;a title="http://umbraco.codeplex.com/workitem/8162" href="http://umbraco.codeplex.com/workitem/8162"&gt;http://umbraco.codeplex.com/workitem/8162&lt;/a&gt;) and it’s now a reality! So without further adieu, here’s the complete database diagram. If you stare at it long enough you might notice some constraints missing which may be true, but this is by design (I assure you :). I’ve attempted to compact the diagram to as small as possible but no matter which way you cut it, it’s a bit crazy. Enjoy! (click the image to see the full size)  &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;a href="/image.axd?picture=image_6.png" target="_blank"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="/image.axd?picture=image_thumb_6.png" width="570" height="497"&gt;&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Thu, 23 Mar 2023 15:08:14 Z</pubDate>
      <a10:updated>2023-03-23T15:08:14Z</a10:updated>
    </item>
  </channel>
</rss>