{"id":10531,"date":"2017-10-11T06:35:00","date_gmt":"2017-10-11T04:35:00","guid":{"rendered":"https:\/\/www.dbi-services.com\/blog\/oracle-database-multilingual-engine-mle\/"},"modified":"2017-10-11T06:35:00","modified_gmt":"2017-10-11T04:35:00","slug":"oracle-database-multilingual-engine-mle","status":"publish","type":"post","link":"https:\/\/www.dbi-services.com\/blog\/oracle-database-multilingual-engine-mle\/","title":{"rendered":"Oracle Database Multilingual Engine (MLE)"},"content":{"rendered":"<h2>By Franck Pachot<\/h2>\n<p>.<br \/>\nMy <a href=\"https:\/\/www.dbi-services.com\/blog\/odc-appreciation-day-javascript-in-the-database\/\" target=\"_blank\" rel=\"noopener noreferrer\">ODC appreciation blog post<\/a> was about Javascript in the database running in the beta of the Oracle Database Multilingual Engine (MLE). Here I&#8217;ll detail my first test which is a comparison, in performance, between a package written in Javascript, running in the MLE, and one written and running in PL\/SQL.<br \/>\n<!--more--><br \/>\nI&#8217;ve downloaded the 12GB .ova from <a href=\"http:\/\/www.oracle.com\/technetwork\/database\/multilingual-engine\/overview\/index.html\" target=\"_blank\" rel=\"noopener noreferrer\">OTN<\/a>, installed the latest <a href=\"http:\/\/www.oracle.com\/technetwork\/developer-tools\/sqlcl\/downloads\/index.html\" target=\"_blank\" rel=\"noopener noreferrer\">SQLcl<\/a>, and I&#8217;m ready to load my first Javascript procedure. I want something simple that I can run a lot of times because I want to test my main concern when running code in a different engine: the context switch between the SQL engine and the procedural one.<\/p>\n<p>My kid&#8217;s maths exercises were about GCD (greatest common divisor) this week-end so I grabbed the <a href=\"http:\/\/pages.pacificcoast.net\/~cazelais\/euclid.html\" target=\"_blank\" rel=\"noopener noreferrer\">Euclid&#8217;s algorithm in Javascript<\/a>. This algorithm was the first program I ever wrote long time ago, on ZX-81, in BASIC. Now in Javascript it can use recursion. So here is my gcd.js file:<\/p>\n<pre><code>\nmodule.exports.gcd = function (a, b) {\n function gcd(a, b) {\n if (b == 0)\n   {return a}\n else\n   {return gcd(b, a % b)}\n }\nreturn gcd(a,b)\n}\n<\/code><\/pre>\n<p>We need strong typing to be able to load it as a stored procedure, so here is the TypeScript definition in gcd.d.ts<\/p>\n<pre><code>\nexport function gcd(a:number, b:number ) : number;\n<\/code><\/pre>\n<p>I load it with the dbjs utility, which I run in verbose mode:<\/p>\n<pre><code>\n[oracle@dbml MLE]$ dbjs deploy -vv gcd.js -u demo -p demo -c \/\/localhost:1521\/DBML\ndeploy: command called  \/media\/sf_share\/MLE\/gcd.js oracle\nOracle backend: starting transpiler\ngcd: processed function\nOracle backend: opening connection to database\ngcd.js: retrieving functions\ndropModule: called with  gcd.js\nloadModule: called with gcd.js\nBEGIN\nEXECUTE IMMEDIATE 'CREATE PACKAGE GCD AS\nFUNCTION GCD(\"p0\" IN NUMBER, \"p1\" IN NUMBER) RETURN NUMBER AS LANGUAGE JS LIBRARY \"gcd.js\" NAME \"gcd\" PARAMETERS(\"p0\" DOUBLE, \"p1\" DOUBLE);\nEND GCD;';\nEND;\n: generated PLSQL\n+ gcd.js\n\u2514\u2500\u252c gcd\n  \u2514\u2500\u2500 SCALAR FUNCTION GCD.GCD(\"p0\" IN NUMBER, \"p1\" IN NUMBER) RETURN NUMBER\n<\/code><\/pre>\n<p>As it is mentioned in the verbose log, the Javascript code is transpiled. My guess is that the Javascript is parsed by the Oracle Truffle framework and compiled by Oracle GaalVM. More info in the <a href=\"http:\/\/www.oracle.com\/technetwork\/oracle-labs\/program-languages\/overview\/index.html\" target=\"_blank\" rel=\"noopener noreferrer\">One VM to Rule Them All<\/a> paper. <\/p>\n<p>This has loaded the package, the library and an &#8216;undefined&#8217; object of type 144 (this MLE is in beta so not all dictionary views have been updated):<\/p>\n<pre><code>\nSQL&gt; select * from dba_objects where owner='DEMO';\n&nbsp;\nOWNER   OBJECT_NAME   SUBOBJECT_NAME   OBJECT_ID   DATA_OBJECT_ID   OBJECT_TYPE   CREATED                LAST_DDL_TIME          TIMESTAMP             STATUS   TEMPORARY   GENERATED   SECONDARY   NAMESPACE   EDITION_NAME   SHARING   EDITIONABLE   ORACLE_MAINTAINED\n-----   -----------   --------------   ---------   --------------   -----------   -------                -------------          ---------             ------   ---------   ---------   ---------   ---------   ------------   -------   -----------   -----------------\nDEMO    GCD                                  93427                  PACKAGE       09-OCT-2017 15:29:33   09-OCT-2017 15:29:33   2017-10-09:15:29:33   VALID    N           N           N                     1                NONE      Y             N\nDEMO    gcd.js                               93426                  LIBRARY       09-OCT-2017 15:29:33   09-OCT-2017 15:29:33   2017-10-09:15:29:33   VALID    N           N           N                     1                NONE      Y             N\nDEMO    gcd.js                               93425                  UNDEFINED     09-OCT-2017 15:29:33   09-OCT-2017 15:29:33   2017-10-09:15:29:33   VALID    N           N           N                   129                NONE                    N\n&nbsp;\n&nbsp;\nSQL&gt; select * from sys.obj$ where obj# in (select object_id from dba_objects where owner='DEMO');\n&nbsp;\nOBJ#    DATAOBJ#   OWNER#   NAME         NAMESPACE   SUBNAME   TYPE#   CTIME                  MTIME                  STIME                  STATUS   REMOTEOWNER   LINKNAME   FLAGS   OID$   SPARE1   SPARE2   SPARE3   SPARE4   SPARE5   SPARE6   SIGNATURE                          SPARE7   SPARE8   SPARE9\n----    --------   ------   ----         ---------   -------   -----   -----                  -----                  -----                  ------   -----------   --------   -----   ----   ------   ------   ------   ------   ------   ------   ---------                          ------   ------   ------\n  93427                 284 GCD                    1                 9 09-OCT-2017 15:29:33   09-OCT-2017 15:29:33   09-OCT-2017 15:29:33          1                                0               6    65535      284                            51713CBD7509C7BDA23B4805C3E662DF          0        0        0\n  93426                 284 gcd.js                 1                22 09-OCT-2017 15:29:33   09-OCT-2017 15:29:33   09-OCT-2017 15:29:33          1                                0               6    65535      284                            8ABC0DDB16E96DC9586A7738071548F0          0        0        0\n  93425                 284 gcd.js               129               144 09-OCT-2017 15:29:33   09-OCT-2017 15:29:33   09-OCT-2017 15:29:33          1                                0               6    65535      284                                                                      0        0        0\n<\/code><\/pre>\n<h3>MLE Javascript<\/h3>\n<p>So, I&#8217;ve executed the function multiple times for each one of 10 millions rows:<\/p>\n<pre><code>\nSQL&gt; select distinct gcd(rownum,rownum+1),gcd(rownum,rownum+2),gcd(rownum,rownum+3) from xmltable('1 to 10000000');\n&nbsp;\nElapsed: 00:00:17.64\n<\/code><\/pre>\n<p>The execution on 30 million took 17 seconds<\/p>\n<h3>PL\/SQL function<\/h3>\n<p>In order to compare, I&#8217;ve created the same in PL\/SQL:<\/p>\n<pre><code>\nSQL&gt; create or replace function gcd_pl(a number, b number) return number as\n  2   function gcd(a number, b number) return number is\n  3   begin\n  4     if b = 0 then\n  5        return a;\n  6     else\n  7        return gcd_pl.gcd(b,mod(a,b));\n  8     end if;\n  9   end;\n 10   begin\n 11     return gcd_pl.gcd(a,b);\n 12   end;\n 13  \/\n<\/code><\/pre>\n<p>Here is the execution:<\/p>\n<pre><code>\nSQL&gt; select distinct gcd_pl(rownum,rownum+1),gcd_pl(rownum,rownum+2),gcd_pl(rownum,rownum+3) from xmltable('1 to 10000000');\n&nbsp;\nElapsed: 00:01:21.05\n<\/code><\/pre>\n<h3>PL\/SQL UDF function<\/h3>\n<p>In 12<i>c<\/i> we can declare a function with the pragma UDF so that it is optimized for calling from SQL<\/p>\n<pre><code>\nSQL&gt; create or replace function gcd_pl_udf(a number, b number) return number as\n  2   pragma UDF;\n  3   function gcd(a number, b number) return number is\n  4   begin\n  5     if b = 0 then\n  6        return a;\n  7     else\n  8        return gcd_pl_udf.gcd(b,mod(a,b));\n  9     end if;\n 10   end;\n 11   begin\n 12     return gcd_pl_udf.gcd(a,b);\n 13   end;\n 14  \/\n<\/code><\/pre>\n<p>Here is the execution:<\/p>\n<pre><code>\nSQL&gt; select distinct gcd_pl_udf(rownum,rownum+1),gcd_pl_udf(rownum,rownum+2),gcd_pl_udf(rownum,rownum+3) from xmltable('1 to 10000000');\n&nbsp;\nElapsed: 00:00:51.85\n<\/code><\/pre>\n<h3>Native compilation<\/h3>\n<p>We can also improve PL\/SQL runtime by compiling it in native, rather than being interpreted on p-code<\/p>\n<pre><code>\nSQL&gt; alter session set plsql_code_type=native;\nSession altered.\n&nbsp;\nSQL&gt; alter function gcd_pl_udf compile;\nFunction altered.\n&nbsp;\nSQL&gt; alter function gcd_pl compile;\nFunction altered.\n<\/code><\/pre>\n<p>and here is the result:<\/p>\n<pre><code>\nSQL&gt; select distinct gcd_pl_udf(rownum,rownum+1),gcd_pl_udf(rownum,rownum+2),gcd_pl_udf(rownum,rownum+3) from xmltable('1 to 10000000');\n&nbsp;\nElapsed: 00:01:10.31\n&nbsp;\nSQL&gt; select distinct gcd_pl_udf(rownum,rownum+1),gcd_pl_udf(rownum,rownum+2),gcd_pl_udf(rownum,rownum+3) from xmltable('1 to 10000000');\n&nbsp;\nElapsed: 00:00:45.54\n<\/code><\/pre>\n<h3>Inline PL\/SQL<\/h3>\n<p>Finally, similar to an UDF function, we can declare the function in the query, inlined in a WITH clause:<\/p>\n<pre><code>\nSQL&gt; with function gcd_pl_in(a number, b number) return number as\n  2   function gcd(a number, b number) return number is\n  3   begin\n  4     if b = 0 then\n  5        return a;\n  6     else\n  7        return gcd(b,mod(a,b));\n  8     end if;\n  9   end;\n 10   begin\n 11     return gcd(a,b);\n 12   end;\n 13  select distinct gcd_pl_in(rownum,rownum+1),gcd_pl_in(rownum,rownum+2),gcd_pl_in(rownum,rownum+3) from xmltable('1 to 10000000')\n 14  \/\n<\/code><\/pre>\n<p>And here is the result:<\/p>\n<pre><code>\nElapsed: 00:00:48.92\n<\/code><\/pre>\n<h3>Elapsed time summary<\/h3>\n<p>Here is a recap of the elapsed time:<br \/>\n<a href=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/CaptureMLE.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/CaptureMLE.png\" alt=\"CaptureMLE\" width=\"348\" height=\"208\" class=\"alignright size-full wp-image-18999\" \/><\/a><\/p>\n<p>Elapsed: 00:00:17.64 for MLE Javascript<br \/>\nElapsed: 00:00:45.54 for PL\/SQL UDF function (native)<br \/>\nElapsed: 00:00:48.92 for Inline PL\/SQL<br \/>\nElapsed: 00:00:51.85 for PL\/SQL UDF function (interpreted)<br \/>\nElapsed: 00:01:10.31 for PL\/SQL function (native)<br \/>\nElapsed: 00:01:21.05 for PL\/SQL function (interpreted)<\/p>\n<p>The top winner is Javascript!<\/p>\n<h3>Perfstat Flame Graph<\/h3>\n<p>My tests were deliberately doing something we should avoid for performance and scalability: call a function for each row, because this involves a lot of time spent in switching the context between the SQL and the procedural engine. But this is however good for code maintainability. This overhead is not easy to measure from the database. We can look at the call stack to see what happens when the process is evaluating the operand (evaopn2) and switches to PL\/SQL (evapls), and what happens besides running the PL\/SQL itself (pfrrun). I have recorded perf-stat for the cases above to display the Flame Graph on the call stack. When looking for more information I remembered that Frits Hoogland already did that so I let you read Frits <a href=\"https:\/\/fritshoogland.wordpress.com\/2016\/01\/23\/plsql-context-switch\/\" target=\"_blank\" rel=\"noopener noreferrer\">part1<\/a> and <a href=\"https:\/\/fritshoogland.wordpress.com\/2016\/01\/25\/plsql-context-switch-part-2\/\" target=\"_blank\" rel=\"noopener noreferrer\">part2<\/a><\/p>\n<p>You can <a href=\"https:\/\/www.dropbox.com\/s\/vfgd52eypxd1sbd\/perf-stat-FlameGraph.zip?dl=0\" target=\"_blank\" rel=\"noopener noreferrer\">download<\/a> my Flame Graphs and here is a summary of .svg name and call stack from operand evaluation to PL\/SQL run:<\/p>\n<pre><code>\nPL\/SQL UDF function (native)        perf-gcd_pl_UDF_native.svg       evaopn2&gt;evapls&gt;peidxrex&gt;penrun\nInline PL\/SQL                       perf-gcd_pl_inline.svg           evaopn2&gt;evapls&gt;kkxmss_speedy_stub&gt;peidxrex&gt;pfrrun&gt;pfrrun_no_tool\nPL\/SQL UDF function (interpreted)   perf-gcd_pl_UDF_interpreted.svg  evaopn2&gt;evapls&gt;peidxexe&gt;pfrrun&gt;pfrrun_no_tool\nPL\/SQL function (native)            perf-gcd_pl_native.svg           evaopn2&gt;evapls&gt;kgmexec&gt;kkxmpexe&gt;kkxdexe&gt;peidxexe&gt;peidxr_run&gt;plsql_run&gt;penrun\nPL\/SQL function (interpreted)       perf-gcd_pl_interpreted.svg      evaopn2&gt;evapls&gt;kgmexec&gt;kkxmpexe&gt;kkxdexe&gt;peidxexe&gt;peidxr_run&gt;plsql_run&gt;pfrrun&gt;pfrrun_no_tool\n<\/code><\/pre>\n<p>But more interesting is the Flame Graph for the JavaScript execution:<br \/>\n<a href=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/CaptureMLEFlame.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/CaptureMLEFlame.png\" alt=\"CaptureMLEFlame\" width=\"1204\" height=\"558\" class=\"aligncenter size-full wp-image-19018\" \/><\/a><\/p>\n<p>My interpretation on this is limited but I don&#8217;t see a stack of context switching function before calling the MLE engine, which is probably the reason why it is fast. Besides the &#8216;unknown&#8217; which is probably the run of the JavaScript itself (the libwalnut.so library has no symbols) we can see that most of the time is in converting SQL data types into JavaScript types at call, and the opposite on return:<\/p>\n<ul>\n<li>com.oracle.walnut.core.types.OraNumberUtil.doubleToNumber<\/li>\n<li>com.oracle.walnut.core.types.OraNumberUtil.numberToDouble<\/li>\n<\/ul>\n<p>This is the price to pay when running a different language, with different data types.<\/p>\n<h3>So what?<\/h3>\n<p>This MultiLingual Engine looks promising, both for functionalities (choose the language to run in the database) and performance (same address space than the SQL, and context switching is minimal). Of course, this is only in beta. There may be more things to implement, with more overhead. For example, we can imagine that if it goes to production there will be some instrumentation to measure time and record it in the Time Model. It may also be optimized further. You can test it (download from the MLE <a href=\"http:\/\/www.oracle.com\/technetwork\/database\/multilingual-engine\/overview\/index.html\" target=\"_blank\" rel=\"noopener noreferrer\">home<\/a> and  give feedback about it (on the MLE <a href=\"https:\/\/community.oracle.com\/community\/database\/developer-tools\/multilingual-engine\/\" target=\"_blank\" rel=\"noopener noreferrer\">forum<\/a>).<\/p>\n<p>This post was about to measuring performance when switching from SQL to PL\/SQL. In next post, I&#8217;ll look at callbacks when running SQL from MLE.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>By Franck Pachot . My ODC appreciation blog post was about Javascript in the database running in the beta of the Oracle Database Multilingual Engine (MLE). Here I&#8217;ll detail my first test which is a comparison, in performance, between a package written in Javascript, running in the MLE, and one written and running in PL\/SQL.<\/p>\n","protected":false},"author":27,"featured_media":10532,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[59],"tags":[1090,1187,1184],"type_dbi":[],"class_list":["post-10531","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oracle","tag-javascript","tag-mle","tag-oracle-18c"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.2 (Yoast SEO v27.2) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Oracle Database Multilingual Engine (MLE) - dbi Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.dbi-services.com\/blog\/oracle-database-multilingual-engine-mle\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Oracle Database Multilingual Engine (MLE)\" \/>\n<meta property=\"og:description\" content=\"By Franck Pachot . My ODC appreciation blog post was about Javascript in the database running in the beta of the Oracle Database Multilingual Engine (MLE). Here I&#8217;ll detail my first test which is a comparison, in performance, between a package written in Javascript, running in the MLE, and one written and running in PL\/SQL.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dbi-services.com\/blog\/oracle-database-multilingual-engine-mle\/\" \/>\n<meta property=\"og:site_name\" content=\"dbi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2017-10-11T04:35:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/CaptureMLE.png\" \/>\n\t<meta property=\"og:image:width\" content=\"348\" \/>\n\t<meta property=\"og:image:height\" content=\"208\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Oracle Team\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Oracle Team\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/oracle-database-multilingual-engine-mle\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/oracle-database-multilingual-engine-mle\/\"},\"author\":{\"name\":\"Oracle Team\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee\"},\"headline\":\"Oracle Database Multilingual Engine (MLE)\",\"datePublished\":\"2017-10-11T04:35:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/oracle-database-multilingual-engine-mle\/\"},\"wordCount\":846,\"commentCount\":0,\"image\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/oracle-database-multilingual-engine-mle\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/CaptureMLE.png\",\"keywords\":[\"JavaScript\",\"MLE\",\"Oracle 18c\"],\"articleSection\":[\"Oracle\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/oracle-database-multilingual-engine-mle\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/oracle-database-multilingual-engine-mle\/\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/oracle-database-multilingual-engine-mle\/\",\"name\":\"Oracle Database Multilingual Engine (MLE) - dbi Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/oracle-database-multilingual-engine-mle\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/oracle-database-multilingual-engine-mle\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/CaptureMLE.png\",\"datePublished\":\"2017-10-11T04:35:00+00:00\",\"author\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/oracle-database-multilingual-engine-mle\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/oracle-database-multilingual-engine-mle\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/oracle-database-multilingual-engine-mle\/#primaryimage\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/CaptureMLE.png\",\"contentUrl\":\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/CaptureMLE.png\",\"width\":348,\"height\":208},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/oracle-database-multilingual-engine-mle\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\/\/www.dbi-services.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Oracle Database Multilingual Engine (MLE)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#website\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/\",\"name\":\"dbi Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee\",\"name\":\"Oracle Team\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g\",\"caption\":\"Oracle Team\"},\"url\":\"https:\/\/www.dbi-services.com\/blog\/author\/oracle-team\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Oracle Database Multilingual Engine (MLE) - dbi Blog","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:\/\/www.dbi-services.com\/blog\/oracle-database-multilingual-engine-mle\/","og_locale":"en_US","og_type":"article","og_title":"Oracle Database Multilingual Engine (MLE)","og_description":"By Franck Pachot . My ODC appreciation blog post was about Javascript in the database running in the beta of the Oracle Database Multilingual Engine (MLE). Here I&#8217;ll detail my first test which is a comparison, in performance, between a package written in Javascript, running in the MLE, and one written and running in PL\/SQL.","og_url":"https:\/\/www.dbi-services.com\/blog\/oracle-database-multilingual-engine-mle\/","og_site_name":"dbi Blog","article_published_time":"2017-10-11T04:35:00+00:00","og_image":[{"width":348,"height":208,"url":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/CaptureMLE.png","type":"image\/png"}],"author":"Oracle Team","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Oracle Team","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.dbi-services.com\/blog\/oracle-database-multilingual-engine-mle\/#article","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/oracle-database-multilingual-engine-mle\/"},"author":{"name":"Oracle Team","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee"},"headline":"Oracle Database Multilingual Engine (MLE)","datePublished":"2017-10-11T04:35:00+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/oracle-database-multilingual-engine-mle\/"},"wordCount":846,"commentCount":0,"image":{"@id":"https:\/\/www.dbi-services.com\/blog\/oracle-database-multilingual-engine-mle\/#primaryimage"},"thumbnailUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/CaptureMLE.png","keywords":["JavaScript","MLE","Oracle 18c"],"articleSection":["Oracle"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.dbi-services.com\/blog\/oracle-database-multilingual-engine-mle\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.dbi-services.com\/blog\/oracle-database-multilingual-engine-mle\/","url":"https:\/\/www.dbi-services.com\/blog\/oracle-database-multilingual-engine-mle\/","name":"Oracle Database Multilingual Engine (MLE) - dbi Blog","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/oracle-database-multilingual-engine-mle\/#primaryimage"},"image":{"@id":"https:\/\/www.dbi-services.com\/blog\/oracle-database-multilingual-engine-mle\/#primaryimage"},"thumbnailUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/CaptureMLE.png","datePublished":"2017-10-11T04:35:00+00:00","author":{"@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee"},"breadcrumb":{"@id":"https:\/\/www.dbi-services.com\/blog\/oracle-database-multilingual-engine-mle\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dbi-services.com\/blog\/oracle-database-multilingual-engine-mle\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.dbi-services.com\/blog\/oracle-database-multilingual-engine-mle\/#primaryimage","url":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/CaptureMLE.png","contentUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/CaptureMLE.png","width":348,"height":208},{"@type":"BreadcrumbList","@id":"https:\/\/www.dbi-services.com\/blog\/oracle-database-multilingual-engine-mle\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.dbi-services.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Oracle Database Multilingual Engine (MLE)"}]},{"@type":"WebSite","@id":"https:\/\/www.dbi-services.com\/blog\/#website","url":"https:\/\/www.dbi-services.com\/blog\/","name":"dbi Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee","name":"Oracle Team","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g","caption":"Oracle Team"},"url":"https:\/\/www.dbi-services.com\/blog\/author\/oracle-team\/"}]}},"_links":{"self":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/10531","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/users\/27"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/comments?post=10531"}],"version-history":[{"count":0,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/10531\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media\/10532"}],"wp:attachment":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media?parent=10531"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/categories?post=10531"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/tags?post=10531"},{"taxonomy":"type","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/type_dbi?post=10531"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}