Rex Dieter adf30af
From e52b57b7a9f0303c0c710e60870d0ec265d32541 Mon Sep 17 00:00:00 2001
Rex Dieter adf30af
From: Milian Wolff <mail@milianw.de>
Rex Dieter adf30af
Date: Mon, 1 Dec 2014 14:11:19 +0100
Rex Dieter adf30af
Subject: [PATCH 19/30] Optimize queries: Do not retrieve known key used in the
Rex Dieter adf30af
 condition.
Rex Dieter adf30af
Rex Dieter adf30af
There is no point in doing a select like:
Rex Dieter adf30af
Rex Dieter adf30af
SELECT foo, bar FROM table WHERE foo = needle;
Rex Dieter adf30af
Rex Dieter adf30af
That can be rewritten to say
Rex Dieter adf30af
Rex Dieter adf30af
SELECT bar FROM table WHERE foo = needle;
Rex Dieter adf30af
Rex Dieter adf30af
This reduces the data traffic with the mysql server. Additionally, it
Rex Dieter adf30af
work-arounds some issues in Qt SQL, which lead to bad performance:
Rex Dieter adf30af
QSqlResult::value incurs multiple temporary allocations, and string
Rex Dieter adf30af
conversions, even to read a simple integer ID for example. Finally,
Rex Dieter adf30af
by reusing an externally provided QString name e.g., we can leverage
Rex Dieter adf30af
Qt's implicit sharing, instead of duplicating the string in a separate
Rex Dieter adf30af
QString instance, with the contents read from SQL server.
Rex Dieter adf30af
Rex Dieter adf30af
REVIEW: 121310
Rex Dieter adf30af
---
Rex Dieter adf30af
 server/src/storage/entities.xsl | 50 +++++++++++++++++++++++++++++------------
Rex Dieter adf30af
 1 file changed, 36 insertions(+), 14 deletions(-)
Rex Dieter adf30af
Rex Dieter adf30af
diff --git a/server/src/storage/entities.xsl b/server/src/storage/entities.xsl
Rex Dieter adf30af
index 9471293..c8fb1fd 100644
Rex Dieter adf30af
--- a/server/src/storage/entities.xsl
Rex Dieter adf30af
+++ b/server/src/storage/entities.xsl
Rex Dieter adf30af
@@ -104,6 +104,12 @@ Q_DECLARE_TYPEINFO( Akonadi::Server::<xsl:value-of select="@name"/>, Q_MOVABLE_T
Rex Dieter adf30af
 
Rex Dieter adf30af
 using namespace Akonadi::Server;
Rex Dieter adf30af
 
Rex Dieter adf30af
+static QStringList removeEntry(QStringList list, const QString& entry)
Rex Dieter adf30af
+{
Rex Dieter adf30af
+  list.removeOne(entry);
Rex Dieter adf30af
+  return list;
Rex Dieter adf30af
+}
Rex Dieter adf30af
+
Rex Dieter adf30af
 <xsl:for-each select="database/table">
Rex Dieter adf30af
 <xsl:call-template name="table-source"/>
Rex Dieter adf30af
 </xsl:for-each>
Rex Dieter adf30af
@@ -179,7 +185,8 @@ set<xsl:value-of select="$methodName"/>( <xsl:call-template name="argument"/> )
Rex Dieter adf30af
     return <xsl:value-of select="$className"/>();
Rex Dieter adf30af
 
Rex Dieter adf30af
   QueryBuilder qb( tableName(), QueryBuilder::Select );
Rex Dieter adf30af
-  qb.addColumns( columnNames() );
Rex Dieter adf30af
+  static const QStringList columns = removeEntry(columnNames(), <xsl:value-of select="$key"/>Column());
Rex Dieter adf30af
+  qb.addColumns( columns );
Rex Dieter adf30af
   qb.addValueCondition( <xsl:value-of select="$key"/>Column(), Query::Equals, <xsl:value-of select="$key"/> );
Rex Dieter adf30af
   if ( !qb.exec() ) {
Rex Dieter adf30af
     akDebug() << "Error during selection of record with <xsl:value-of select="$key"/>"
Rex Dieter adf30af
@@ -191,21 +198,36 @@ set<xsl:value-of select="$methodName"/>( <xsl:call-template name="argument"/> )
Rex Dieter adf30af
     return <xsl:value-of select="$className"/>();
Rex Dieter adf30af
   }
Rex Dieter adf30af
 
Rex Dieter adf30af
+  
Rex Dieter adf30af
+  int valueIndex = 0;
Rex Dieter adf30af
+  <xsl:for-each select="column">
Rex Dieter adf30af
+    const <xsl:value-of select="@type"/> value<xsl:value-of select="position()"/> =
Rex Dieter adf30af
+    <xsl:choose>
Rex Dieter adf30af
+      <xsl:when test="@name=$key">
Rex Dieter adf30af
+        <xsl:value-of select="$key"/>;
Rex Dieter adf30af
+      </xsl:when>
Rex Dieter adf30af
+      <xsl:otherwise>
Rex Dieter adf30af
+        (qb.query().isNull(valueIndex)) ?
Rex Dieter adf30af
+        <xsl:value-of select="@type"/>() :
Rex Dieter adf30af
+        <xsl:choose>
Rex Dieter adf30af
+          <xsl:when test="starts-with(@type,'QString')">
Rex Dieter adf30af
+          Utils::variantToString( qb.query().value( valueIndex ) )
Rex Dieter adf30af
+          </xsl:when>
Rex Dieter adf30af
+          <xsl:when test="starts-with(@type, 'Tristate')">
Rex Dieter adf30af
+          static_cast<Tristate>(qb.query().value( valueIndex ).value<int>())
Rex Dieter adf30af
+          </xsl:when>
Rex Dieter adf30af
+          <xsl:otherwise>
Rex Dieter adf30af
+          qb.query().value( valueIndex ).value<<xsl:value-of select="@type"/>>()
Rex Dieter adf30af
+          </xsl:otherwise>
Rex Dieter adf30af
+        </xsl:choose>
Rex Dieter adf30af
+        ; ++valueIndex;
Rex Dieter adf30af
+      </xsl:otherwise>
Rex Dieter adf30af
+    </xsl:choose>
Rex Dieter adf30af
+  </xsl:for-each>
Rex Dieter adf30af
+
Rex Dieter adf30af
   <xsl:value-of select="$className"/> rv(
Rex Dieter adf30af
   <xsl:for-each select="column">
Rex Dieter adf30af
-    (qb.query().isNull(<xsl:value-of select="position() - 1"/>)) ?
Rex Dieter adf30af
-      <xsl:value-of select="@type"/>() :
Rex Dieter adf30af
-      <xsl:choose>
Rex Dieter adf30af
-        <xsl:when test="starts-with(@type,'QString')">
Rex Dieter adf30af
-      Utils::variantToString( qb.query().value( <xsl:value-of select="position() - 1"/> ) )
Rex Dieter adf30af
-        </xsl:when>
Rex Dieter adf30af
-        <xsl:when test="starts-with(@type, 'Tristate')">
Rex Dieter adf30af
-      static_cast<Tristate>(qb.query().value( <xsl:value-of select="position() - 1"/> ).value<int>())
Rex Dieter adf30af
-        </xsl:when>
Rex Dieter adf30af
-        <xsl:otherwise>
Rex Dieter adf30af
-      qb.query().value( <xsl:value-of select="position() - 1"/> ).value<<xsl:value-of select="@type"/>>()
Rex Dieter adf30af
-        </xsl:otherwise>
Rex Dieter adf30af
-      </xsl:choose>
Rex Dieter adf30af
+    value<xsl:value-of select="position()"/>
Rex Dieter adf30af
     <xsl:if test="position() != last()">,</xsl:if>
Rex Dieter adf30af
   </xsl:for-each>
Rex Dieter adf30af
   );
Rex Dieter adf30af
-- 
Rex Dieter adf30af
2.1.0
Rex Dieter adf30af