{"id":3204,"date":"2020-01-26T17:32:41","date_gmt":"2020-01-26T17:32:41","guid":{"rendered":"https:\/\/nenadnoveljic.com\/blog\/?p=3204"},"modified":"2020-01-26T17:32:44","modified_gmt":"2020-01-26T17:32:44","slug":"orm-overhead","status":"publish","type":"post","link":"https:\/\/nenadnoveljic.com\/blog\/orm-overhead\/","title":{"rendered":"Do You Know Your Object-Relational Mapper&#8217;s Overhead?"},"content":{"rendered":"<h1>ORM<\/h1>\n<p>In a nutshell, an <a href=\"https:\/\/en.wikipedia.org\/wiki\/Object-relational_mapping\">object-relational mapper (ORM)<\/a> is a framework that converts data in a database to application code objects and vice versa. Its main purpose is to simplify coding. There is also a <a href=\"https:\/\/www.yaplex.com\/blog\/micro-orm-vs-orm\">micro ORM<\/a> &#8211; a lightweight ORM, which performs better than a full featured ORM. <a href=\"https:\/\/dapper-tutorial.net\/dapper\">Dapper<\/a> is one such micro ORM for .NET. It can map a single row to an object. Further, it can map a row containing data from multiple tables to multiple object types in a single call. But, what it can&#8217;t do, is to populate nested objects, like the following one:<\/p>\n<pre><code>public class Customer\n{\n\tpublic int CustomerId;\n\tpublic string Name;\n\tpublic <span style=\"color: #ff0000;\">List&lt;Order&gt;<\/span> Orders;\n}\npublic class Order\n{\n        public int Id;\n        public int Amount ;\n        public int CustomerId;\n}  <\/code><\/pre>\n<p>Not only does the <i>Customer<\/i> class above contain customer data, but also a list of orders for a customer. So, the objects have to be initialized by iterating over rows obtained by the join of <i>customers<\/i> and <i>orders<\/i> tables. This is how this can be achieved with Dapper:<\/p>\n<pre><code>var customersDictionary = new Dictionary&lt;int, customer=\"\"&gt;();\nrows = connection.Query&lt;customer, customer=\"\" order,=\"\"&gt;(sql,\n\t(c, o) =&gt;\n\t{\n\t\tCustomer customer;\n\t\tif (!customersDictionary.TryGetValue(c.Id, out customer))\n\t\t{\n\t\t\tcustomersDictionary.Add(c.Id, customer = c);\n\t\t}\n\t\tif (customer.Orders == null)\n\t\t{\n\t\t\tcustomer.Orders = new List();\n\t\t}\n\t\tcustomer.Orders.Add(o);\n\t\treturn customer;\n\t}, splitOn: \"Id\").Distinct().ToList();&lt;\/customer,&gt;&lt;\/int,&gt;<\/code><\/pre>\n<p><a href=\"https:\/\/github.com\/SlapperAutoMapper\/Slapper.AutoMapper\">Slapper.Automapper<\/a> comes in handy here &#8211; the code above can be replaced by a single line:<\/p>\n<pre><code>var customers = Slapper.AutoMapper.Map( connection.Query(sql) );<\/code><\/pre>\n<p>Seductive, isn&#8217;t it?<\/p>\n<p>But, wait&#8230; As we shall see, that&#8217;s not a free lunch. In fact, the price you pay in terms of performance may be huge.<\/p>\n<h1>Performance<\/h1>\n<p>The test consists of populating the list of <i>Customer<\/i> objects. For every row in the <i>customers<\/i> table there are 10 rows in the <i>orders<\/i> table. The tests are performed for different numbers of rows. I used SQL Server 2017, but the results can be extrapolated to any database products, as the test case is designed to stress the ORM, not the database.<\/p>\n<p>Three types of tests were performed:<\/p>\n<ol>\n<li><a href=\"https:\/\/github.com\/nenadnoveljic\/blogs\/blob\/master\/slapper-overhead\/PlainSQLTest.cs\">PlainSQL test<\/a>: it provides a reference. It iterates over the rows and populates an object for each selected row without using any ORMs.<\/li>\n<li><a href=\"https:\/\/github.com\/nenadnoveljic\/blogs\/blob\/master\/slapper-overhead\/DapperTest.cs\">Dapper test<\/a>: uses Dapper micro ORM for populating customer data in the object and a custom code to populate the Orders list for each customer.<\/li>\n<li><a href=\"https:\/\/github.com\/nenadnoveljic\/blogs\/blob\/master\/slapper-overhead\/SlapperTest.cs\">Slapper.Automapper test<\/a>: uses Slapper.Automapper framework to populate the list of <i>Customer<\/i> objects.<\/li>\n<\/ol>\n<p>The following graph displays the test results:<\/p>\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"468\" height=\"277\" src=\"https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2020\/01\/Slapper_graph.png\" alt=\"\" class=\"wp-image-3216\" srcset=\"https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2020\/01\/Slapper_graph.png 468w, https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2020\/01\/Slapper_graph-300x178.png 300w\" sizes=\"auto, (max-width: 468px) 100vw, 468px\" \/><\/figure>\n\n\n<p>As you can see, Slapper.Autodapper introduces a massive overhead. In contrast, the overhead of Dapper is insignificant.<\/p>\n<p>Note that due to the logarithmic scale on both axis, the overhead is much larger than it visually appears. As the overhead per row is constant, the optimized queries returning many rows will be most affected.<\/p>\n<h1>Profiling .NET<\/h1>\n<p>The reason for this serious performance degradation becomes obvious when looking at the profiled .NET execution when the query returned 100&#8217;000 rows:<\/p>\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"823\" height=\"88\" src=\"https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2020\/01\/Slapper_stack_high.png\" alt=\"\" class=\"wp-image-3217\" srcset=\"https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2020\/01\/Slapper_stack_high.png 823w, https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2020\/01\/Slapper_stack_high-300x32.png 300w, https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2020\/01\/Slapper_stack_high-768x82.png 768w\" sizes=\"auto, (max-width: 823px) 100vw, 823px\" \/><\/figure>\n\n\n<p>As you can see, Slapper.Automapper relies on Dapper. However, only 5% was spent within the Dapper code. To get an idea what was executed we have to look deeper into the stack:<\/p>\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"883\" height=\"194\" src=\"https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2020\/01\/Slapper_stack_low2.png\" alt=\"\" class=\"wp-image-3249\" srcset=\"https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2020\/01\/Slapper_stack_low2.png 883w, https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2020\/01\/Slapper_stack_low2-300x66.png 300w, https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2020\/01\/Slapper_stack_low2-768x169.png 768w\" sizes=\"auto, (max-width: 883px) 100vw, 883px\" \/><\/figure>\n\n\n<p>Some procedures were executed 100&#8217;000 times, that is, for every row. We can also see that the introspection (<a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/api\/system.reflection.fieldinfo?view=netframework-4.8\"><i>System.Reflection.RuntimeFieldInfo.GetCustomAttributes<\/i><\/a>) was executed 300&#8217;000 times &#8211; which equals the number of rows multiplied by the number of non-id attributes. Introspection discovers and accesses metadata. Relying on the introspection came to no surprise, because Slapper.AutoMapper converts dynamic data into strongly typed data types. But, the problem is that the mapping code gets executed for each row, instead of just once at the beginning. Consequently, the efficiency could be dramatically improved by simply caching the mapping results.<\/p>\n<h1>Testing framework<\/h1>\n<p>I performed tests with a little <a href=\"https:\/\/github.com\/nenadnoveljic\/blogs\/tree\/master\/slapper-overhead\">home-grown framework<\/a> written in C#. It&#8217;s very basic &#8211; I quickly developed it to quantify the overhead while troubleshooting a production issue.<\/p>\n<p>There are a couple of parameters that can be configured:<\/p>\n\n<table id=\"tablepress-10\" class=\"tablepress tablepress-id-10\">\n<thead>\n<tr class=\"row-1\">\n\t<th class=\"column-1\">Parameter<\/th><th class=\"column-2\">Meaning<\/th>\n<\/tr>\n<\/thead>\n<tbody class=\"row-striping row-hover\">\n<tr class=\"row-2\">\n\t<td class=\"column-1\">connectionStrings<\/td><td class=\"column-2\">database connection string<\/td>\n<\/tr>\n<tr class=\"row-3\">\n\t<td class=\"column-1\">Iterations<\/td><td class=\"column-2\">number of tests to perform (for each type)<\/td>\n<\/tr>\n<tr class=\"row-4\">\n\t<td class=\"column-1\">Rows<\/td><td class=\"column-2\">number of customers rows to select<\/td>\n<\/tr>\n<tr class=\"row-5\">\n\t<td class=\"column-1\">Threads<\/td><td class=\"column-2\">number of parallel threads<\/td>\n<\/tr>\n<tr class=\"row-6\">\n\t<td class=\"column-1\">Tests<\/td><td class=\"column-2\">comma-separated list of test types (PlainSQLTest,DapperTest,SlapperTest)<\/td>\n<\/tr>\n<tr class=\"row-7\">\n\t<td class=\"column-1\">Verbosity<\/td><td class=\"column-2\">0 - basic information with the median elapsed times <br \/>\n1- elapsed time for each run<br \/>\n2 - first three rows for each execution<br \/>\n(I used 1 and 2 only during development)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<!-- #tablepress-10 from cache -->\n<p>Use <a href=\"https:\/\/github.com\/nenadnoveljic\/blogs\/blob\/master\/slapper-overhead\/create_test_data.sql\"><i>create_test_data.sql<\/i><\/a> for creating test data.<\/p>\n<p>To test with another database product you&#8217;d need to: replace the driver, adjust the connect string and adapt <a href=\"https:\/\/github.com\/nenadnoveljic\/blogs\/blob\/master\/slapper-overhead\/create_test_data.sql\"><i>create_test_data.sql<\/i><\/a> accordingly.<\/p>\n<p>To test another ORM, add a test class which implements the <a href=\"https:\/\/github.com\/nenadnoveljic\/blogs\/blob\/master\/slapper-overhead\/ITest.cs\"><i>ITest<\/i><\/a> interface. If the ORM populates <em>Customer<\/em> object, it&#8217;s more convenient to inherit the abstract class <a href=\"https:\/\/github.com\/nenadnoveljic\/blogs\/blob\/master\/slapper-overhead\/TestReturnsObjectList.cs\"><i>TestReturnsObjectList<\/i><\/a> , which itself implements <a href=\"https:\/\/github.com\/nenadnoveljic\/blogs\/blob\/master\/slapper-overhead\/ITest.cs\"><i>ITest<\/i><\/a>. Also, don&#8217;t forget to specify the class name in the configuration parameter&nbsp;<em>Tests<\/em>.<\/p>\n<p>If the framework proves useful I&#8217;ll define an interface class for test cases, so that they can be easily added and customized without touching the core.<\/p>\n<h1>Conclusion<\/h1>\n<p>In conclusion, developers love using ORMs to simplify the application code. On the downside, it&#8217;s a black box and an additional abstraction layer, which might give rise to performance problems with non-obvious root causes. When complaining about &#8220;database problems&#8221;, developers are often mistaking ORM API calls for database calls. On the other hand, DBAs can&#8217;t see any issues in the database when the time is spent within the ORM. Consequently, the inability to quickly identify the root cause can elicit finger pointing and unproductive discussions. Understanding the fundamental principle that an ORM call comprises of more than just a database call, can significantly reduce the resolution time and improve the collaboration. Also, learning how to quickly triage by using database instrumentation and application code profiling pays high dividends. Finally, I provided a framework for building models for quantifying the ORM performance overhead.<\/p>","protected":false},"excerpt":{"rendered":"<p>A call to ORM API can comprise of much more than a database call. Its overhead can be measured. <a href=\"https:\/\/nenadnoveljic.com\/blog\/orm-overhead\/\" class=\"more-link\">Continue Reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[17],"tags":[],"class_list":["post-3204","post","type-post","status-publish","format-standard","hentry","category-sql-server"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Do You Know Your Object-Relational Mapper&#039;s Overhead? - All-round Database Topics<\/title>\n<meta name=\"description\" content=\"A call to ORM API can comprise of much more than a database call. Its overhead can be measured.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/nenadnoveljic.com\/blog\/orm-overhead\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Do You Know Your Object-Relational Mapper&#039;s Overhead? - All-round Database Topics\" \/>\n<meta property=\"og:description\" content=\"A call to ORM API can comprise of much more than a database call. Its overhead can be measured.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/nenadnoveljic.com\/blog\/orm-overhead\/\" \/>\n<meta property=\"og:site_name\" content=\"All-round Database Topics\" \/>\n<meta property=\"article:published_time\" content=\"2020-01-26T17:32:41+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2020-01-26T17:32:44+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2020\/01\/Slapper_graph.png\" \/>\n<meta name=\"author\" content=\"Nenad Noveljic\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@NenadNoveljic\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Nenad Noveljic\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/orm-overhead\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/orm-overhead\\\/\"},\"author\":{\"name\":\"Nenad Noveljic\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/#\\\/schema\\\/person\\\/51458d9dd86dbbdd19f5add451d44efa\"},\"headline\":\"Do You Know Your Object-Relational Mapper&#8217;s Overhead?\",\"datePublished\":\"2020-01-26T17:32:41+00:00\",\"dateModified\":\"2020-01-26T17:32:44+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/orm-overhead\\\/\"},\"wordCount\":838,\"commentCount\":2,\"image\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/orm-overhead\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/wp-content\\\/uploads\\\/2020\\\/01\\\/Slapper_graph.png\",\"articleSection\":[\"SQL Server\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/orm-overhead\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/orm-overhead\\\/\",\"url\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/orm-overhead\\\/\",\"name\":\"Do You Know Your Object-Relational Mapper's Overhead? - All-round Database Topics\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/orm-overhead\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/orm-overhead\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/wp-content\\\/uploads\\\/2020\\\/01\\\/Slapper_graph.png\",\"datePublished\":\"2020-01-26T17:32:41+00:00\",\"dateModified\":\"2020-01-26T17:32:44+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/#\\\/schema\\\/person\\\/51458d9dd86dbbdd19f5add451d44efa\"},\"description\":\"A call to ORM API can comprise of much more than a database call. Its overhead can be measured.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/orm-overhead\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/orm-overhead\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/orm-overhead\\\/#primaryimage\",\"url\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/wp-content\\\/uploads\\\/2020\\\/01\\\/Slapper_graph.png\",\"contentUrl\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/wp-content\\\/uploads\\\/2020\\\/01\\\/Slapper_graph.png\",\"width\":468,\"height\":277},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/orm-overhead\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Do You Know Your Object-Relational Mapper&#8217;s Overhead?\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/\",\"name\":\"All-round Database Topics\",\"description\":\"Nenad Noveljic\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/#\\\/schema\\\/person\\\/51458d9dd86dbbdd19f5add451d44efa\",\"name\":\"Nenad Noveljic\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a97b796613ea48ec8a7b79c8ffe1c685dcffc920c68121f6238d5caab5070670?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a97b796613ea48ec8a7b79c8ffe1c685dcffc920c68121f6238d5caab5070670?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a97b796613ea48ec8a7b79c8ffe1c685dcffc920c68121f6238d5caab5070670?s=96&d=mm&r=g\",\"caption\":\"Nenad Noveljic\"},\"sameAs\":[\"nenad-noveljic-9b746a6\",\"https:\\\/\\\/x.com\\\/NenadNoveljic\"],\"url\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/author\\\/nenad\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Do You Know Your Object-Relational Mapper's Overhead? - All-round Database Topics","description":"A call to ORM API can comprise of much more than a database call. Its overhead can be measured.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/nenadnoveljic.com\/blog\/orm-overhead\/","og_locale":"en_US","og_type":"article","og_title":"Do You Know Your Object-Relational Mapper's Overhead? - All-round Database Topics","og_description":"A call to ORM API can comprise of much more than a database call. Its overhead can be measured.","og_url":"https:\/\/nenadnoveljic.com\/blog\/orm-overhead\/","og_site_name":"All-round Database Topics","article_published_time":"2020-01-26T17:32:41+00:00","article_modified_time":"2020-01-26T17:32:44+00:00","og_image":[{"url":"https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2020\/01\/Slapper_graph.png","type":"","width":"","height":""}],"author":"Nenad Noveljic","twitter_card":"summary_large_image","twitter_creator":"@NenadNoveljic","twitter_misc":{"Written by":"Nenad Noveljic","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/nenadnoveljic.com\/blog\/orm-overhead\/#article","isPartOf":{"@id":"https:\/\/nenadnoveljic.com\/blog\/orm-overhead\/"},"author":{"name":"Nenad Noveljic","@id":"https:\/\/nenadnoveljic.com\/blog\/#\/schema\/person\/51458d9dd86dbbdd19f5add451d44efa"},"headline":"Do You Know Your Object-Relational Mapper&#8217;s Overhead?","datePublished":"2020-01-26T17:32:41+00:00","dateModified":"2020-01-26T17:32:44+00:00","mainEntityOfPage":{"@id":"https:\/\/nenadnoveljic.com\/blog\/orm-overhead\/"},"wordCount":838,"commentCount":2,"image":{"@id":"https:\/\/nenadnoveljic.com\/blog\/orm-overhead\/#primaryimage"},"thumbnailUrl":"https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2020\/01\/Slapper_graph.png","articleSection":["SQL Server"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/nenadnoveljic.com\/blog\/orm-overhead\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/nenadnoveljic.com\/blog\/orm-overhead\/","url":"https:\/\/nenadnoveljic.com\/blog\/orm-overhead\/","name":"Do You Know Your Object-Relational Mapper's Overhead? - All-round Database Topics","isPartOf":{"@id":"https:\/\/nenadnoveljic.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/nenadnoveljic.com\/blog\/orm-overhead\/#primaryimage"},"image":{"@id":"https:\/\/nenadnoveljic.com\/blog\/orm-overhead\/#primaryimage"},"thumbnailUrl":"https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2020\/01\/Slapper_graph.png","datePublished":"2020-01-26T17:32:41+00:00","dateModified":"2020-01-26T17:32:44+00:00","author":{"@id":"https:\/\/nenadnoveljic.com\/blog\/#\/schema\/person\/51458d9dd86dbbdd19f5add451d44efa"},"description":"A call to ORM API can comprise of much more than a database call. Its overhead can be measured.","breadcrumb":{"@id":"https:\/\/nenadnoveljic.com\/blog\/orm-overhead\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/nenadnoveljic.com\/blog\/orm-overhead\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/nenadnoveljic.com\/blog\/orm-overhead\/#primaryimage","url":"https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2020\/01\/Slapper_graph.png","contentUrl":"https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2020\/01\/Slapper_graph.png","width":468,"height":277},{"@type":"BreadcrumbList","@id":"https:\/\/nenadnoveljic.com\/blog\/orm-overhead\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/nenadnoveljic.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Do You Know Your Object-Relational Mapper&#8217;s Overhead?"}]},{"@type":"WebSite","@id":"https:\/\/nenadnoveljic.com\/blog\/#website","url":"https:\/\/nenadnoveljic.com\/blog\/","name":"All-round Database Topics","description":"Nenad Noveljic","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/nenadnoveljic.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/nenadnoveljic.com\/blog\/#\/schema\/person\/51458d9dd86dbbdd19f5add451d44efa","name":"Nenad Noveljic","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/a97b796613ea48ec8a7b79c8ffe1c685dcffc920c68121f6238d5caab5070670?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/a97b796613ea48ec8a7b79c8ffe1c685dcffc920c68121f6238d5caab5070670?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/a97b796613ea48ec8a7b79c8ffe1c685dcffc920c68121f6238d5caab5070670?s=96&d=mm&r=g","caption":"Nenad Noveljic"},"sameAs":["nenad-noveljic-9b746a6","https:\/\/x.com\/NenadNoveljic"],"url":"https:\/\/nenadnoveljic.com\/blog\/author\/nenad\/"}]}},"_links":{"self":[{"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/posts\/3204","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/comments?post=3204"}],"version-history":[{"count":1,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/posts\/3204\/revisions"}],"predecessor-version":[{"id":3253,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/posts\/3204\/revisions\/3253"}],"wp:attachment":[{"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/media?parent=3204"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/categories?post=3204"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/tags?post=3204"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}