{"id":2465,"date":"2019-04-04T17:35:19","date_gmt":"2019-04-04T17:35:19","guid":{"rendered":"https:\/\/nenadnoveljic.com\/blog\/?p=2465"},"modified":"2022-02-17T15:30:03","modified_gmt":"2022-02-17T15:30:03","slug":"comparing-tsql-and-pl-sql-performance","status":"publish","type":"post","link":"https:\/\/nenadnoveljic.com\/blog\/comparing-tsql-and-pl-sql-performance\/","title":{"rendered":"Comparing TSQL and PL\/SQL Performance"},"content":{"rendered":"<h1>Measuring performance<\/h1>\n<p>I measured the number of loop iterations per ms in TSQL (SQL server 2017) and PL\/SQL (Oracle 18 XE) on a Windows server. Besides that, I compared them with the C implementation, just to get an idea of the overhead when executing a simple loop in a database.<\/p>\n<p><a href=\"https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2019\/04\/performance_single_thread.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone  wp-image-2477\" src=\"https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2019\/04\/performance_single_thread-300x186.png\" alt=\"\" width=\"394\" height=\"244\" srcset=\"https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2019\/04\/performance_single_thread-300x186.png 300w, https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2019\/04\/performance_single_thread.png 455w\" sizes=\"auto, (max-width: 394px) 100vw, 394px\" \/><\/a><\/p>\n<p>Notice that the Y-axis scale is logarithmic, so the differences are much larger than they visually appear.<\/p>\n<p>We can see that Oracle outperforms SQL Server by an order of magnitude.<\/p>\n<p>Next, I&#8217;ll be focusing on how the execution time changes with a concurrent load.<\/p>\n<h1>Scalability<\/h1>\n<p>Since I don&#8217;t have multi-core licences for Oracle on Windows, I measured the execution times on Solaris x64. In order to compare the databases on different platforms, I normalized the mean execution time by dividing it with the execution time of a single session test:<\/p>\n<p class=\"ql-left-displayed-equation\" style=\"line-height: 42px;\"><span class=\"ql-right-eqno\"> (1) <\/span><span class=\"ql-left-eqno\"> &nbsp; <\/span><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/nenadnoveljic.com\/blog\/wp-content\/ql-cache\/quicklatex.com-121d3fd3d141130a8047bd84548f9761_l3.png\" height=\"42\" width=\"84\" class=\"ql-img-displayed-equation quicklatex-auto-format\" alt=\"&#92;&#98;&#101;&#103;&#105;&#110;&#123;&#101;&#113;&#117;&#97;&#116;&#105;&#111;&#110;&#42;&#125; &#84;&#40;&#78;&#41;&#32;&#61;&#32;&#92;&#102;&#114;&#97;&#99;&#123;&#92;&#111;&#118;&#101;&#114;&#108;&#105;&#110;&#101;&#123;&#116;&#125;&#95;&#110;&#125;&#123;&#116;&#95;&#49;&#125; &#92;&#101;&#110;&#100;&#123;&#101;&#113;&#117;&#97;&#116;&#105;&#111;&#110;&#42;&#125;\" title=\"Rendered by QuickLaTeX.com\"\/><\/p>\n<p>In other words, T(N) is a factor by which the performance degrades when N sessions are running simultaneously.<\/p>\n<p><a href=\"https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2019\/04\/execution_times_n_threads.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone  wp-image-2475\" src=\"https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2019\/04\/execution_times_n_threads-300x174.png\" alt=\"\" width=\"405\" height=\"235\" srcset=\"https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2019\/04\/execution_times_n_threads-300x174.png 300w, https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2019\/04\/execution_times_n_threads.png 464w\" sizes=\"auto, (max-width: 405px) 100vw, 405px\" \/><\/a><\/p>\n<p>Unlike Oracle, SQL Server doesn&#8217;t scale at all &#8211; the execution time dramatically increases with the load. For example, the execution time is twice as long when 5 sessions are executing the load.<\/p>\n<p>In conclusion, not only does SQL Server perform much worse than Oracle, but also it doesn&#8217;t scale.<\/p>\n<p>As the procedure is completely CPU-bound, stack profiling will provide a clue to where the time goes.<\/p>\n<h1>Stack profiling<\/h1>\n<p>I used <a href=\"https:\/\/docs.microsoft.com\/en-us\/windows-hardware\/test\/wpt\/\">Windows Performance Toolkit<\/a> for collecting and aggregating stacks and also Bruce Dawson&#8217;s awesome <a href=\"https:\/\/randomascii.wordpress.com\/2015\/04\/14\/uiforetw-windows-performance-made-easier\/\">UIforETW<\/a> for facilitating the whole process.<\/p>\n<p><a href=\"https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2019\/04\/tsql_stack.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone  wp-image-2479\" src=\"https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2019\/04\/tsql_stack-300x70.png\" alt=\"\" width=\"459\" height=\"107\" srcset=\"https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2019\/04\/tsql_stack-300x70.png 300w, https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2019\/04\/tsql_stack-640x150.png 640w, https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2019\/04\/tsql_stack.png 642w\" sizes=\"auto, (max-width: 459px) 100vw, 459px\" \/><\/a><\/p>\n<p>As you can see, the stack part beginning with the function CMetaStmtSet::PxstmtGetEmbeddedXstmt consumed more than 30% of the total execution time. So, it makes sense to inspect the lowest function on the stack: sqllang!CStatement::AddRef.<\/p>\n<h1>Serialization<\/h1>\n<p>By observing its input and output with WINDBG, we can see that the function increments the memory location passed through the RCX register. Actually, the exact memory location is RCX+7C0h.<\/p>\n<p>The calls to sqllang!CStatement::AddRef are traced with WINDBG &#8211; the following commands spool the thread information and the RCX register value:<\/p>\n<pre><code>bp sqllang!CStatement::AddRef \"~.; r rcx; gc\"<\/code><\/pre>\n<p>Here&#8217;s the excerpt from the rather long output:<\/p>\n<pre><code>...\n.  <span style=\"color: #ff0000;\">6<\/span>  Id: 1bac.1ff4 Suspend: 1 Teb: 000000aa`cb8f2000 Unfrozen\n      Start: sqldk!SchedulerManager::ThreadEntryPoint (00007ffc`1eda7c10)\n      Priority: 0  Priority class: 32  Affinity: 3e0\nrcx=0<span style=\"color: #ff0000;\">00001fad58e93b0<\/span>\n.<span style=\"color: #ff0000;\">137<\/span>  Id: 1bac.1b54 Suspend: 1 Teb: 000000aa`cb906000 Unfrozen\n      Start: sqldk!SchedulerManager::ThreadEntryPoint (00007ffc`1eda7c10)\n      Priority: 0  Priority class: 32  Affinity: 1f\nrcx=<span style=\"color: #ff0000;\">000001fad58e93b0<\/span>\n.  <span style=\"color: #ff0000;\">6<\/span>  Id: 1bac.1ff4 Suspend: 1 Teb: 000000aa`cb8f2000 Unfrozen\n      Start: sqldk!SchedulerManager::ThreadEntryPoint (00007ffc`1eda7c10)\n      Priority: 0  Priority class: 32  Affinity: 3e0\nrcx=<span style=\"color: #ff0000;\">000001fad58e89c0<\/span>\n.<span style=\"color: #ff0000;\">137<\/span>  Id: 1bac.1b54 Suspend: 1 Teb: 000000aa`cb906000 Unfrozen\n      Start: sqldk!SchedulerManager::ThreadEntryPoint (00007ffc`1eda7c10)\n      Priority: 0  Priority class: 32  Affinity: 1f\nrcx=<span style=\"color: #ff0000;\">000001fad58e89c0<\/span>\n.  6  Id: 1bac.1ff4 Suspend: 1 Teb: 000000aa`cb8f2000 Unfrozen\n      Start: sqldk!SchedulerManager::ThreadEntryPoint (00007ffc`1eda7c10)\n      Priority: 0  Priority class: 32  Affinity: 3e0\nrcx=000001fad58e93b0\n.<span style=\"color: #ff0000;\">137<\/span>  Id: 1bac.1b54 Suspend: 1 Teb: 000000aa`cb906000 Unfrozen\n      Start: sqldk!SchedulerManager::ThreadEntryPoint (00007ffc`1eda7c10)\n      Priority: 0  Priority class: 32  Affinity: 1f\nrcx=<span style=\"color: #ff0000;\">000001fad58e93b0<\/span>\n.  <span style=\"color: #ff0000;\">6<\/span>  Id: 1bac.1ff4 Suspend: 1 Teb: 000000aa`cb8f2000 Unfrozen\n      Start: sqldk!SchedulerManager::ThreadEntryPoint (00007ffc`1eda7c10)\n      Priority: 0  Priority class: 32  Affinity: 3e0\nrcx=<span style=\"color: #ff0000;\">000001fad58e89c0<\/span>\n.<span style=\"color: #ff0000;\">137<\/span>  Id: 1bac.1b54 Suspend: 1 Teb: 000000aa`cb906000 Unfrozen\n      Start: sqldk!SchedulerManager::ThreadEntryPoint (00007ffc`1eda7c10)\n      Priority: 0  Priority class: 32  Affinity: 1f\n...<\/code><\/pre>\n<p>The pattern above is repeated over and over again, because the function gets called several times during each loop iteration.<\/p>\n<p>Furthermore, there were two threads working in parallel: <span style=\"color: #ff0000;\">6<\/span> and <span style=\"color: #ff0000;\">137<\/span>. Curiously, both of them were trying to increment the same memory locations: <span style=\"color: #ff0000;\">000001fad58e93b0<\/span> and <span style=\"color: #ff0000;\">000001fad58e89c0<\/span>.<\/p>\n<p>These target locations are in the database cache, more precisely in its region annotated as MEMOBJ_EXECUTE.<\/p>\n<pre><code>SELECT memory_object_address  \n     , pages_in_bytes  \n     , bytes_used  \n     , type  \n   FROM sys.dm_os_memory_objects order \n   by memory_object_address\n\nmemory_object_address\tpages_in_bytes\tbytes_used\ttype\n<span style=\"color: #ff0000;\">0x000001FAD5880060<\/span>\t32768\tNULL\tMEMOBJ_EXECUTE\n0x000001FAD58EC060\t16384\tNULL\tMEMOBJ_COMPILE_ADHOC<\/code><\/pre>\n<p>Since multiple threads are incrementing the same location, they must utilize the atomic instructions of processors to atomically update a memory location. That involves specifying a lock prefix, which will assert a lock on the cache and sometimes even on the bus. Consequently, its frequent usage will impair performance.<\/p>\n<p>This locking mechanism is nothing unusual within a database and it&#8217;s normally used to serialize changes to a shared resource. In fact, that&#8217;s exactly how latches are implemented <a href=\"https:\/\/www.apress.com\/de\/book\/9781430239543\">[Lewis 2011]<\/a>: &#8220;Essentially a latch is the combination of a memory location in the SGA and an atomic CPU operation that can be used to check and change the value of that location.&#8221;<\/p>\n<p>When executing a stored procedure, for example, a latch might be used to count the number of sessions executing the procedure, to prevent other sessions from altering it. When the execution finishes, the session counts itself off. Once the value is decremented to zero, it means that nobody&#8217;s executing the procedure anymore, so, another session can now acquire the latch and proceed with a DDL.<\/p>\n<p>Generally speaking, acquiring a latch is a rather normal event, but what&#8217;s completely strange in this case is the huge number of these operations for a single stored procedure call. It almost looks like the individual lines are protected by the latch instead of the whole procedure.<\/p>\n<p>That&#8217;s quite a serious disadvantage and, as it turns out, the main reason for the TSQL inefficiency.<\/p>\n<p>Let&#8217;s see now if this excessive serialization code path can be somehow avoided.<\/p>\n<h1>Natively compiled stored procedures<\/h1>\n<p>There&#8217;s a possibility to compile TSQL and store it in a DLL. This feature is referred to as <a href=\"https:\/\/docs.microsoft.com\/en-us\/sql\/relational-databases\/in-memory-oltp\/natively-compiled-stored-procedures?view=sql-server-2017\">natively compiled stored procedure<\/a><\/p>\n<p>This indeed boosts the throughput. In fact, the efficiency has approached the C implementation.<\/p>\n<p><a href=\"https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2019\/04\/performance_single_thread_lin2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone  wp-image-2478\" src=\"https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2019\/04\/performance_single_thread_lin2-300x182.png\" alt=\"\" width=\"407\" height=\"247\" srcset=\"https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2019\/04\/performance_single_thread_lin2-300x182.png 300w, https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2019\/04\/performance_single_thread_lin2.png 545w\" sizes=\"auto, (max-width: 407px) 100vw, 407px\" \/><\/a><\/p>\n<p>Also, the scalability has approved with the native compilation.<\/p>\n<p><a href=\"https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2019\/04\/normalized_execution_times_compiled.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone  wp-image-2476\" src=\"https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2019\/04\/normalized_execution_times_compiled-300x175.png\" alt=\"\" width=\"422\" height=\"246\" srcset=\"https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2019\/04\/normalized_execution_times_compiled-300x175.png 300w, https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2019\/04\/normalized_execution_times_compiled.png 476w\" sizes=\"auto, (max-width: 422px) 100vw, 422px\" \/><\/a><\/p>\n<p>However, natively compiled procedures impose some quite serious limitations. For instance, they only work with memory-optimized tables &#8211; neither conventional nor temporary tables are supported. Neither can they reference conventional stored procedures.<\/p>\n<p>As a consequence, you can&#8217;t just compile the procedure and, by doing so, make it run X times faster.<\/p>\n<h1>Summary<\/h1>\n<p>In summary, there is a serious performance and scalability issue with SQL Server TSQL, which is caused by excessive serialization of shared memory access. Not only does Oracle PL\/SQL perform an order of magnitude better, but also it scales perfectly. While natively compiled procedures perform really good in SQL Server, they also come with some serious limitations, which, in my opinion, render them unusable for most conventional use cases.<\/p>\n<h1>Appendix<\/h1>\n<p>The scripts for creating stored procedures used in this blog post are in <a href=\"https:\/\/github.com\/nenadnoveljic\/blogs\/blob\/master\/comparing_TSQL_and_PLSQL_performance\">my Github repository<\/a>.<\/p>\n<p>You can use <a href=\"https:\/\/github.com\/nenadnoveljic\/sqlserver_cpu_benchmark\/blob\/master\/Invoke-Load.ps1\">Invoke-Load.ps1<\/a> for starting them concurrently.<\/p>\n<h1>References<\/h1>\n<ul>\n<li><a href=\"https:\/\/software.intel.com\/en-us\/articles\/implementing-scalable-atomic-locks-for-multi-core-intel-em64t-and-ia32-architectures\">[Chynoweth 2012]<\/a> Michael Chynoweth (Intel). (2012, March 7). Implementing Scalable Atomic Locks for Multi-Core Intel\u00ae EM64T and IA32 Architectures<\/li>\n<li><a href=\"https:\/\/www.apress.com\/de\/book\/9781430239543\">[Lewis 2011]<\/a> Jonathan Lewis. (2011). Oracle Core: Essential Internals for DBAs and Developers<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Why Oracle outperforms SQL Server <a href=\"https:\/\/nenadnoveljic.com\/blog\/comparing-tsql-and-pl-sql-performance\/\" 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":[21,5,52,17],"tags":[],"class_list":["post-2465","post","type-post","status-publish","format-standard","hentry","category-comparison-oracle-sql-server","category-oracle","category-pl-sql","category-sql-server"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Comparing TSQL and PL\/SQL Performance - All-round Database Topics<\/title>\n<meta name=\"description\" content=\"Why Oracle outperforms SQL Server\" \/>\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\/comparing-tsql-and-pl-sql-performance\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Comparing TSQL and PL\/SQL Performance - All-round Database Topics\" \/>\n<meta property=\"og:description\" content=\"Why Oracle outperforms SQL Server\" \/>\n<meta property=\"og:url\" content=\"https:\/\/nenadnoveljic.com\/blog\/comparing-tsql-and-pl-sql-performance\/\" \/>\n<meta property=\"og:site_name\" content=\"All-round Database Topics\" \/>\n<meta property=\"article:published_time\" content=\"2019-04-04T17:35:19+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-02-17T15:30:03+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2019\/04\/performance_single_thread-300x186.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=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/comparing-tsql-and-pl-sql-performance\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/comparing-tsql-and-pl-sql-performance\\\/\"},\"author\":{\"name\":\"Nenad Noveljic\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/#\\\/schema\\\/person\\\/51458d9dd86dbbdd19f5add451d44efa\"},\"headline\":\"Comparing TSQL and PL\\\/SQL Performance\",\"datePublished\":\"2019-04-04T17:35:19+00:00\",\"dateModified\":\"2022-02-17T15:30:03+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/comparing-tsql-and-pl-sql-performance\\\/\"},\"wordCount\":921,\"commentCount\":4,\"image\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/comparing-tsql-and-pl-sql-performance\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/04\\\/performance_single_thread-300x186.png\",\"articleSection\":[\"Comparison Oracle-SQL Server\",\"Oracle\",\"PL\\\/SQL\",\"SQL Server\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/comparing-tsql-and-pl-sql-performance\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/comparing-tsql-and-pl-sql-performance\\\/\",\"url\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/comparing-tsql-and-pl-sql-performance\\\/\",\"name\":\"Comparing TSQL and PL\\\/SQL Performance - All-round Database Topics\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/comparing-tsql-and-pl-sql-performance\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/comparing-tsql-and-pl-sql-performance\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/04\\\/performance_single_thread-300x186.png\",\"datePublished\":\"2019-04-04T17:35:19+00:00\",\"dateModified\":\"2022-02-17T15:30:03+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/#\\\/schema\\\/person\\\/51458d9dd86dbbdd19f5add451d44efa\"},\"description\":\"Why Oracle outperforms SQL Server\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/comparing-tsql-and-pl-sql-performance\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/comparing-tsql-and-pl-sql-performance\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/comparing-tsql-and-pl-sql-performance\\\/#primaryimage\",\"url\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/04\\\/performance_single_thread.png\",\"contentUrl\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/04\\\/performance_single_thread.png\",\"width\":455,\"height\":282},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/comparing-tsql-and-pl-sql-performance\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Comparing TSQL and PL\\\/SQL Performance\"}]},{\"@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":"Comparing TSQL and PL\/SQL Performance - All-round Database Topics","description":"Why Oracle outperforms SQL Server","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\/comparing-tsql-and-pl-sql-performance\/","og_locale":"en_US","og_type":"article","og_title":"Comparing TSQL and PL\/SQL Performance - All-round Database Topics","og_description":"Why Oracle outperforms SQL Server","og_url":"https:\/\/nenadnoveljic.com\/blog\/comparing-tsql-and-pl-sql-performance\/","og_site_name":"All-round Database Topics","article_published_time":"2019-04-04T17:35:19+00:00","article_modified_time":"2022-02-17T15:30:03+00:00","og_image":[{"url":"https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2019\/04\/performance_single_thread-300x186.png","type":"","width":"","height":""}],"author":"Nenad Noveljic","twitter_card":"summary_large_image","twitter_creator":"@NenadNoveljic","twitter_misc":{"Written by":"Nenad Noveljic","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/nenadnoveljic.com\/blog\/comparing-tsql-and-pl-sql-performance\/#article","isPartOf":{"@id":"https:\/\/nenadnoveljic.com\/blog\/comparing-tsql-and-pl-sql-performance\/"},"author":{"name":"Nenad Noveljic","@id":"https:\/\/nenadnoveljic.com\/blog\/#\/schema\/person\/51458d9dd86dbbdd19f5add451d44efa"},"headline":"Comparing TSQL and PL\/SQL Performance","datePublished":"2019-04-04T17:35:19+00:00","dateModified":"2022-02-17T15:30:03+00:00","mainEntityOfPage":{"@id":"https:\/\/nenadnoveljic.com\/blog\/comparing-tsql-and-pl-sql-performance\/"},"wordCount":921,"commentCount":4,"image":{"@id":"https:\/\/nenadnoveljic.com\/blog\/comparing-tsql-and-pl-sql-performance\/#primaryimage"},"thumbnailUrl":"https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2019\/04\/performance_single_thread-300x186.png","articleSection":["Comparison Oracle-SQL Server","Oracle","PL\/SQL","SQL Server"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/nenadnoveljic.com\/blog\/comparing-tsql-and-pl-sql-performance\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/nenadnoveljic.com\/blog\/comparing-tsql-and-pl-sql-performance\/","url":"https:\/\/nenadnoveljic.com\/blog\/comparing-tsql-and-pl-sql-performance\/","name":"Comparing TSQL and PL\/SQL Performance - All-round Database Topics","isPartOf":{"@id":"https:\/\/nenadnoveljic.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/nenadnoveljic.com\/blog\/comparing-tsql-and-pl-sql-performance\/#primaryimage"},"image":{"@id":"https:\/\/nenadnoveljic.com\/blog\/comparing-tsql-and-pl-sql-performance\/#primaryimage"},"thumbnailUrl":"https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2019\/04\/performance_single_thread-300x186.png","datePublished":"2019-04-04T17:35:19+00:00","dateModified":"2022-02-17T15:30:03+00:00","author":{"@id":"https:\/\/nenadnoveljic.com\/blog\/#\/schema\/person\/51458d9dd86dbbdd19f5add451d44efa"},"description":"Why Oracle outperforms SQL Server","breadcrumb":{"@id":"https:\/\/nenadnoveljic.com\/blog\/comparing-tsql-and-pl-sql-performance\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/nenadnoveljic.com\/blog\/comparing-tsql-and-pl-sql-performance\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/nenadnoveljic.com\/blog\/comparing-tsql-and-pl-sql-performance\/#primaryimage","url":"https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2019\/04\/performance_single_thread.png","contentUrl":"https:\/\/nenadnoveljic.com\/blog\/wp-content\/uploads\/2019\/04\/performance_single_thread.png","width":455,"height":282},{"@type":"BreadcrumbList","@id":"https:\/\/nenadnoveljic.com\/blog\/comparing-tsql-and-pl-sql-performance\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/nenadnoveljic.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Comparing TSQL and PL\/SQL Performance"}]},{"@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\/2465","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=2465"}],"version-history":[{"count":1,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/posts\/2465\/revisions"}],"predecessor-version":[{"id":4171,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/posts\/2465\/revisions\/4171"}],"wp:attachment":[{"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/media?parent=2465"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/categories?post=2465"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/tags?post=2465"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}