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