{"id":1835,"date":"2011-07-22T14:30:52","date_gmt":"2011-07-22T13:30:52","guid":{"rendered":"http:\/\/www.gamlor.info\/wordpress\/?p=1835"},"modified":"2021-07-03T13:31:35","modified_gmt":"2021-07-03T12:31:35","slug":"ravendb-preventing-database-slaughter","status":"publish","type":"post","link":"https:\/\/www.gamlor.info\/wordpress\/2011\/07\/ravendb-preventing-database-slaughter\/","title":{"rendered":"RavenDB: Preventing Database Slaughter"},"content":{"rendered":"<p>After we\u2019ve covered the <a href=\"https:\/\/www.gamlor.info\/wordpress\/2011\/06\/first-steps-with-reavendb\/\">basics<\/a>, <a href=\"https:\/\/www.gamlor.info\/wordpress\/2011\/06\/ravendb-documents\/\">documents<\/a> and <a href=\"https:\/\/www.gamlor.info\/wordpress\/2011\/07\/ravendb-queries-and-indexes\/\">queries<\/a>, we take a short look at another \u2018feature\u2019 of RavenDB. Have you ever had this issue: You\u2019ve developed nice application which runs fine during development. Then you go to a production system and your application becomes slow or even dies under higher loads. And the database administrator comes angry to your team and asks who\u2019s killing the database. What happened? Well often these issues are related to bad queries and unbound result sets. Let\u2019s see what RavenDB does to prevent these situations.<\/p>\n<h2>No Unbound Result Sets<\/h2>\n<p>What do most databases do when you run a query like \u2018give me all .NET related blog posts\u2019? Well they try to fulfill that request. What\u2019s the issue with that? Often the result set too is big. When too large result sets hits your application it will choke on it. How do we  prevent that? We add limitations to the result set size. However how many times have you forgotten to add that limitation in your application? I think it\u2019s a very common mistake to forget it and get an unbounded result set. Well RavenDB just doesn\u2019t allow unbounded set. Let\u2019s see it in action (btw: The domain classes are <a href=\"https:\/\/gist.github.com\/1099334#file_domain_model.cs\">here<\/a>, the <a href=\"https:\/\/gist.github.com\/1099334#file_store_stuff.cs\">insert code<\/a> here):<br \/>\n<script src=\"https:\/\/gist.github.com\/1099334.js?file=LimitIteration.cs\"><\/script><noscript><pre><code class=\"language-c# c#\">var dotNetBlogPosts = from p in session.Query&lt;BlogPost&gt;()\n\t\t\twhere p.Category == &quot;.NET&quot;\n\t\t\tselect p;\nConsole.Out.WriteLine(&quot;Number of blog posts {0}&quot;,dotNetBlogPosts.Count());\nvar countPosts = 0;\nforeach (var blogPost in dotNetBlogPosts)\n{\n\t\/\/ do something\n\tcountPosts++;\n}\nConsole.Out.WriteLine(&quot;Iterated through {0} posts&quot;, countPosts);<\/code><\/pre><\/noscript><\/p>\n<p>When we run the code we get following output:<br \/>\n<\/p>\n<p>So when you don\u2019t specify any limit then a result will contain at maximum 128 entries. Therefore you should always specify how many entries you want. For that just use the Take() and Skip() operators on your result:<br \/>\n<\/p>\n<div id=\"attachment_1842\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/07\/result-limit.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1842\" src=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/07\/result-limit-300x137.png\" alt=\"Limits Are Your Friend\" title=\"result-limit\" class=\"size-medium wp-image-1842\" width=\"300\" height=\"137\" srcset=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/07\/result-limit-300x137.png 300w, https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/07\/result-limit.png 800w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-1842\" class=\"wp-caption-text\">Limits Are Your Friend<\/p><\/div>\n<h2>Server Side Result Set Limitation<\/h2>\n<p>Let\u2019s run another experiment: We just specify an insanely high limit for our query. Like this:<br \/>\n<\/p>\n<p>What we notice is that RavenDB only returns 1024 documents from the server. It prevents that giant result sets are transferred across the wire. If you really want to have more data you need to page across the data with Skip() and Take(). Alternatively you could configure the server to allow a higher limit, but that\u2019s not the recommended way to get larger result sets.<\/p>\n<div id=\"attachment_1843\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/07\/server-limits.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1843\" src=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/07\/server-limits-300x182.png\" alt=\"Also the server has its limits\" title=\"server-limits\" class=\"size-medium wp-image-1843\" width=\"300\" height=\"182\" srcset=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/07\/server-limits-300x182.png 300w, https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/07\/server-limits.png 800w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-1843\" class=\"wp-caption-text\">Also the server has its limits<\/p><\/div>\n<h2>Request Limitations<\/h2>\n<p>One of the common performance issue in applications is doing too many requests and round trips to the database. (Especially feared as the \u2018N+1 Selects\u2019 pitfall with ORMs). This often just happens by accident, because we call different methods which all do some operations on the database. So what happens when we do that with RavenDB? Let\u2019s find out. In this example we load a few blog posts and the go off and load all comments for a blog post.<br \/>\n<\/p>\n<p>In this situation RavenDB will throw an exception telling us that we reached the request limit. By default each session can only do 30 requests to the server. When it does more RavenDB will complain. And most of the time we really shouldn\u2019t use that many requests. For example when we want to load related documents we can tell that RavenDB directly and avoid addition requests, like we\u2019ve saw in this <a href=\"https:\/\/www.gamlor.info\/wordpress\/2011\/06\/ravendb-documents\/\">blog post<\/a>. If we really need more requests we also can increase the limit:<br \/>\n<\/p>\n<div id=\"attachment_1844\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/07\/request-limits.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1844\" src=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/07\/request-limits-300x201.png\" alt=\"Request Limits\" title=\"request-limits\" class=\"size-medium wp-image-1844\" width=\"300\" height=\"201\" srcset=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/07\/request-limits-300x201.png 300w, https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/07\/request-limits.png 800w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-1844\" class=\"wp-caption-text\">Request Limits<\/p><\/div>\n<h2>Timeouts<\/h2>\n<p>Another protection of RavenDB is that operations have timeouts. Let\u2019s run another example. We first insert tons of blog posts and the use a dynamic index to get non stale results:<br \/>\n<\/p>\n<p>What will happen? We almost certainly get an time out exception telling us that it took to long to get non-stale results for that dynamic index. That\u2019s because the background indexing hasn\u2019t finished yet for all the new inserted documents. This also clearly demonstrates that RavenDB isn\u2019t build for write-heavy scenarios, but for read heavy applications.<br \/>\nThis also can occur when the server has just been started, because then it first needs to build up all the indexes used by the application. However in everyday use that should rarely happen.<\/p>\n<div id=\"attachment_1845\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/07\/timeout.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1845\" src=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/07\/timeout-300x258.png\" alt=\"Timeouts\" title=\"timeout\" class=\"size-medium wp-image-1845\" width=\"300\" height=\"258\" srcset=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/07\/timeout-300x258.png 300w, https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/07\/timeout.png 700w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-1845\" class=\"wp-caption-text\">Timeouts<\/p><\/div>\n<h2>Conclusion &amp; Next Time<\/h2>\n<p>We\u2019ve seen that RavenDB aggressively protects itself and our application from accidental overload scenarios. That also means that we need to ensure that we limit the result sets to reasonable sizes.<\/p>\n<p>I\u2019m yet sure what the topic of the next blog post will be, but there will one for sure.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>After we\u2019ve covered the basics, documents and queries, we take a short look at another \u2018feature\u2019 of RavenDB. Have you ever had this issue: You\u2019ve developed nice application which runs&hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_links_to":"","_links_to_target":""},"categories":[126,231],"tags":[21,296],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts\/1835"}],"collection":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/comments?post=1835"}],"version-history":[{"count":19,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts\/1835\/revisions"}],"predecessor-version":[{"id":3887,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts\/1835\/revisions\/3887"}],"wp:attachment":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/media?parent=1835"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/categories?post=1835"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/tags?post=1835"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}