Преглед на файлове

[mORMot] use `update table set .. from values (), ()` pattern (#8128)

* [mORMot] use `update table set .. from values (), ()` pattern for rawupdates

* upgrade to latest mORMot2 revision

---------

Co-authored-by: pavel.mash <[email protected]>
pavelmash преди 2 години
родител
ревизия
974c4876be
променени са 2 файла, в които са добавени 11 реда и са изтрити 18 реда
  1. 1 1
      frameworks/Pascal/mormot/setup_and_build.sh
  2. 10 17
      frameworks/Pascal/mormot/src/raw.pas

+ 1 - 1
frameworks/Pascal/mormot/setup_and_build.sh

@@ -35,7 +35,7 @@ echo "Download statics from $URL ..."
 wget -qO- "$URL" | tar -xz -C ./libs/mORMot/static
 
 # uncomment for fixed commit URL
-URL=https://github.com/synopse/mORMot2/tarball/edf377a61aa5ac99add92d144480b12095f578c2
+URL=https://github.com/synopse/mORMot2/tarball/08dd4a1898fa2e66b659f0679f7a038b3b2f2c65
 #URL="https://api.github.com/repos/synopse/mORMot2/tarball/$USED_TAG"
 echo "Download and unpacking mORMot sources from $URL ..."
 wget -qO- "$URL" | tar -xz -C ./libs/mORMot  --strip-components=1

+ 10 - 17
frameworks/Pascal/mormot/src/raw.pas

@@ -441,24 +441,18 @@ begin
   LastComputeUpdateSqlSafe.Lock;
   if cnt <> LastComputeUpdateSqlCnt then
   begin
-    // update table set randomNumber = CASE id when ? then ? when ? then ? ...
-    // when ? then ? else randomNumber end where id in (?,?,?,?,?)
-    // - this weird syntax gives best number for TFB /rawupdates?queries=20 but
-    // seems not good for smaller or higher count - we won't include it in the
-    // ORM but only for our RAW results - as other frameworks (e.g. ntex) do
+    // update table set .. from values (), (), ... where id = id
+    // we won't include it in the ORM but only for our RAW results
     LastComputeUpdateSqlCnt := cnt;
     W := TTextWriter.CreateOwnedStream(tmp);
     try
-      W.AddShort('UPDATE world SET randomnumber = CASE id');
-      for i := 1 to cnt do
-        W.AddShort(' when ? then ?');
-      W.AddShort(' else randomNumber end where id in (');
-      repeat
-        W.Add('?', ',');
-        dec(cnt);
-      until cnt = 0;
+      W.AddShort('UPDATE world SET randomNumber = v.randomNumber FROM (VALUES');
+      for i := 1 to cnt do begin
+        W.AddShort('(?::integer, ?::integer)');
+        W.Add(',');
+      end;
       W.CancelLastComma;
-      W.Add(')');
+      W.AddShort(' order by 1) AS v (id, randomNumber) WHERE world.id = v.id');
       W.SetText(LastComputeUpdateSql);
     finally
       W.Free;
@@ -484,7 +478,7 @@ begin
   // generate new randoms
   for i := 0 to cnt - 1 do
     res[i].randomNumber := ComputeRandomWorld;
-  if cnt > 15 then
+  if cnt > 20 then
   begin
     // fill parameters arrays for update with nested select (PostgreSQL only)
     setLength(ids{%H-}, cnt);
@@ -500,13 +494,12 @@ begin
   end
   else
   begin
-    // fill parameters for update up to 15 items as CASE .. WHEN .. THEN ..
+    // fill parameters for update up to 20 items as VALUES(?,?),(?,?),...
     stmt := conn.NewStatementPrepared(ComputeUpdateSql(cnt), false, true);
     for i := 0 to cnt - 1 do
     begin
       stmt.Bind(i * 2 + 1, res[i].id);
       stmt.Bind(i * 2 + 2, res[i].randomNumber);
-      stmt.Bind(cnt * 2 + i + 1, res[i].id);
     end;
   end;
   stmt.ExecutePrepared;