<!-- 
RSS generated by JIRA (5.2.7#850-sha1:b2af0c8dc8537b36121c6a579fabbdf79fc919e5) at Fri May 24 10:26:55 UTC 2013

It is possible to restrict the fields that are returned in this document by specifying the 'field' parameter in your request.
For example, to request only the issue key and summary add field=key&field=summary to the URL of your request.
For example:
http://www.doctrine-project.org/jira/si/jira.issueviews:issue-xml/DDC-1602/DDC-1602.xml?field=key&field=summary
-->
<rss version="0.92" >
<channel>
    <title>Doctrine Project</title>
    <link>http://www.doctrine-project.org/jira</link>
    <description>This file is an XML representation of an issue</description>
    <language>en-us</language>    <build-info>
        <version>5.2.7</version>
        <build-number>850</build-number>
        <build-date>21-02-2013</build-date>
    </build-info>

<item>
            <title>[DDC-1602] Executors for Class Table Inheritance (JOINED) are extremely slow on MySQL</title>
                <link>http://www.doctrine-project.org/jira/browse/DDC-1602</link>
                <project id="10032" key="DDC">Doctrine 2 - ORM</project>
                        <description>&lt;p&gt;Update and delete executors for Class Table Inheritance (JOINED) are extremely slow on MySQL platform. It is most probably due to use of subselect on the temporary table.&lt;br/&gt;
The slowdown is really significant as the table size increases. As an example, lets have a root entity with one subclass:&lt;/p&gt;

&lt;div class=&quot;code panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;codeContent panelContent&quot;&gt;
&lt;pre class=&quot;code-java&quot;&gt;/**
 * @Entity
 * @InheritanceType(&lt;span class=&quot;code-quote&quot;&gt;&quot;JOINED&quot;&lt;/span&gt;)
 * @DiscriminatorColumn(name=&lt;span class=&quot;code-quote&quot;&gt;&quot;discr&quot;&lt;/span&gt;, type=&lt;span class=&quot;code-quote&quot;&gt;&quot;string&quot;&lt;/span&gt;)
 * @DiscriminatorMap({&lt;span class=&quot;code-quote&quot;&gt;&quot;root&quot;&lt;/span&gt; = &lt;span class=&quot;code-quote&quot;&gt;&quot;Root&quot;&lt;/span&gt;, &lt;span class=&quot;code-quote&quot;&gt;&quot;a&quot;&lt;/span&gt; = &lt;span class=&quot;code-quote&quot;&gt;&quot;SubA&quot;&lt;/span&gt;})
 */
class Root
{
	/**
	 * @Column(type=&lt;span class=&quot;code-quote&quot;&gt;&quot;integer&quot;&lt;/span&gt;)
	 * @Id
	 * @GeneratedValue
	 */
	&lt;span class=&quot;code-keyword&quot;&gt;private&lt;/span&gt; $id;

	/**
	 * @Column(type=&lt;span class=&quot;code-quote&quot;&gt;&quot;integer&quot;&lt;/span&gt;)
	 */
	&lt;span class=&quot;code-keyword&quot;&gt;private&lt;/span&gt; $xyz;
}
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;code panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;codeContent panelContent&quot;&gt;
&lt;pre class=&quot;code-java&quot;&gt;/**
 * @Entity
 */
class SubA &lt;span class=&quot;code-keyword&quot;&gt;extends&lt;/span&gt; Root
{
	/**
	 * @Column(type=&lt;span class=&quot;code-quote&quot;&gt;&quot;integer&quot;&lt;/span&gt;)
	 */
	&lt;span class=&quot;code-keyword&quot;&gt;private&lt;/span&gt; $foo;
}
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now lets perform a simple DQL UPDATE:&lt;/p&gt;
&lt;div class=&quot;code panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;codeContent panelContent&quot;&gt;
&lt;pre class=&quot;code-java&quot;&gt;UPDATE Entities\Root r SET r.xyz = 123 WHERE r.id &amp;gt; ?
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;(note: always the upper half of entries)&lt;br/&gt;
Which creates following SQLs:&lt;/p&gt;
&lt;div class=&quot;code panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;codeContent panelContent&quot;&gt;
&lt;pre class=&quot;code-java&quot;&gt;CREATE TEMPORARY TABLE Root_id_tmp (id INT NOT NULL)
INSERT INTO Root_id_tmp (id) SELECT t0.id FROM Root t0 LEFT JOIN SubA s0_ ON t0.id = s0_.id WHERE t0.id &amp;gt; 25000
UPDATE Root SET xyz = 123 WHERE (id) IN (SELECT id FROM Root_id_tmp)
DROP TEMPORARY TABLE Root_id_tmp
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The time spent on this on MySQL 5.5.17 and PostgreSQL 9.1 is:&lt;/p&gt;

&lt;table class=&apos;confluenceTable&apos;&gt;&lt;tbody&gt;
&lt;tr&gt;
&lt;th class=&apos;confluenceTh&apos;&gt; no. of entries &lt;/th&gt;
&lt;th class=&apos;confluenceTh&apos;&gt; 500   &lt;/th&gt;
&lt;th class=&apos;confluenceTh&apos;&gt; 1000  &lt;/th&gt;
&lt;th class=&apos;confluenceTh&apos;&gt; 2500 &lt;/th&gt;
&lt;th class=&apos;confluenceTh&apos;&gt; 5000 &lt;/th&gt;
&lt;th class=&apos;confluenceTh&apos;&gt; 10000 &lt;/th&gt;
&lt;th class=&apos;confluenceTh&apos;&gt; 20000 &lt;/th&gt;
&lt;th class=&apos;confluenceTh&apos;&gt; 50000 &lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&apos;confluenceTd&apos;&gt; &lt;b&gt;MySQL&lt;/b&gt;             &lt;/td&gt;
&lt;td class=&apos;confluenceTd&apos;&gt; 0.26s &lt;/td&gt;
&lt;td class=&apos;confluenceTd&apos;&gt;  0.35s &lt;/td&gt;
&lt;td class=&apos;confluenceTd&apos;&gt; 1.1s  &lt;/td&gt;
&lt;td class=&apos;confluenceTd&apos;&gt; 3.68s  &lt;/td&gt;
&lt;td class=&apos;confluenceTd&apos;&gt; 14.13s &lt;/td&gt;
&lt;td class=&apos;confluenceTd&apos;&gt; 54.44s &lt;/td&gt;
&lt;td class=&apos;confluenceTd&apos;&gt; 338s &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&apos;confluenceTd&apos;&gt; &lt;b&gt;PostgreSQL&lt;/b&gt;   &lt;/td&gt;
&lt;td class=&apos;confluenceTd&apos;&gt; 0.10s &lt;/td&gt;
&lt;td class=&apos;confluenceTd&apos;&gt; 0.10s &lt;/td&gt;
&lt;td class=&apos;confluenceTd&apos;&gt; 0.13s &lt;/td&gt;
&lt;td class=&apos;confluenceTd&apos;&gt; 0.15s  &lt;/td&gt;
&lt;td class=&apos;confluenceTd&apos;&gt; 0.22s   &lt;/td&gt;
&lt;td class=&apos;confluenceTd&apos;&gt; 0.35s   &lt;/td&gt;
&lt;td class=&apos;confluenceTd&apos;&gt; 1.01s &lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;


&lt;p&gt;As you can see, MySQL is drastically slower on even relatively small tables. This currently makes Doctrine unusable for this type of inheritance on MySQL. The solution probably would be to avoid subselect in WHERE clause in Doctrine\ORM\Query\Exec\MultiTableUpdateExecutor and Doctrine\ORM\Query\Exec\MultiTableDeleteExecutor.&lt;/p&gt;

&lt;p&gt;Feel free to try/modify the test script yourself, it&apos;s &lt;a href=&quot;https://github.com/Majkl578/doctrine2-slow-executors&quot; class=&quot;external-link&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;</description>
                <environment>Debian, MySQL 5.5.17</environment>
            <key id="13362">DDC-1602</key>
            <summary>Executors for Class Table Inheritance (JOINED) are extremely slow on MySQL</summary>
                <type id="4" iconUrl="http://www.doctrine-project.org/jira/images/icons/issuetypes/improvement.png">Improvement</type>
                                <priority id="3" iconUrl="http://www.doctrine-project.org/jira/images/icons/priorities/major.png">Major</priority>
                    <status id="1" iconUrl="http://www.doctrine-project.org/jira/images/icons/statuses/open.png">Open</status>
                    <resolution id="-1">Unresolved</resolution>
                    <security id="10000">All</security>
                        <assignee username="beberlei">Benjamin Eberlei</assignee>
                                <reporter username="majkl578">Michael Moravec</reporter>
                        <labels>
                    </labels>
                <created>Sun, 15 Jan 2012 19:45:05 +0000</created>
                <updated>Wed, 27 Jun 2012 17:57:43 +0000</updated>
                                    <version>2.2-BETA2</version>
                                                <component>DQL</component>
                        <due></due>
                    <votes>3</votes>
                        <watches>2</watches>
                        <comments>
                    <comment id="17269" author="beberlei" created="Sun, 15 Jan 2012 22:59:14 +0000"  >&lt;p&gt;Its not a bug as it works. The performance drawback of JTI is discussed in the manual &lt;a href=&quot;http://www.doctrine-project.org/docs/orm/2.1/en/reference/inheritance-mapping.html&quot; class=&quot;external-link&quot;&gt;http://www.doctrine-project.org/docs/orm/2.1/en/reference/inheritance-mapping.html&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Changing this would be an improvement where we would hint if databases prefer subselects or joins for different operations. This would increase complexity of the SQL generation since now we are getting along with just one SQL generation strategy.&lt;/p&gt;</comment>
                    <comment id="17938" author="majkl578" created="Fri, 11 May 2012 11:02:42 +0000"  >&lt;p&gt;Any chance to get this implemented before 2.3?&lt;/p&gt;</comment>
                    <comment id="17939" author="majkl578" created="Fri, 11 May 2012 14:03:31 +0000"  >&lt;p&gt;I&apos;ve made a change in DBAL and ORM code to implement a solution issue. It&apos;s currently more likely a proof of concept.&lt;/p&gt;

&lt;p&gt;With the change, my results are (approximately):&lt;/p&gt;
&lt;table class=&apos;confluenceTable&apos;&gt;&lt;tbody&gt;
&lt;tr&gt;
&lt;th class=&apos;confluenceTh&apos;&gt; no. of entries &lt;/th&gt;
&lt;th class=&apos;confluenceTh&apos;&gt; 500   &lt;/th&gt;
&lt;th class=&apos;confluenceTh&apos;&gt; 1000  &lt;/th&gt;
&lt;th class=&apos;confluenceTh&apos;&gt; 2500 &lt;/th&gt;
&lt;th class=&apos;confluenceTh&apos;&gt; 5000 &lt;/th&gt;
&lt;th class=&apos;confluenceTh&apos;&gt; 10000 &lt;/th&gt;
&lt;th class=&apos;confluenceTh&apos;&gt; 20000 &lt;/th&gt;
&lt;th class=&apos;confluenceTh&apos;&gt; 50000 &lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&apos;confluenceTd&apos;&gt; &lt;b&gt;MySQL&lt;/b&gt;             &lt;/td&gt;
&lt;td class=&apos;confluenceTd&apos;&gt; 0.17s &lt;/td&gt;
&lt;td class=&apos;confluenceTd&apos;&gt;  0.19s &lt;/td&gt;
&lt;td class=&apos;confluenceTd&apos;&gt; 0.21s  &lt;/td&gt;
&lt;td class=&apos;confluenceTd&apos;&gt; 0.26s  &lt;/td&gt;
&lt;td class=&apos;confluenceTd&apos;&gt; 0.27s &lt;/td&gt;
&lt;td class=&apos;confluenceTd&apos;&gt; 0.37s &lt;/td&gt;
&lt;td class=&apos;confluenceTd&apos;&gt; 0.92s &lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;


&lt;p&gt;Currently only update executor was changed.&lt;br/&gt;
DBAL branch with changes: &lt;a href=&quot;https://github.com/Majkl578/doctrine-dbal/tree/DDC-1602&quot; class=&quot;external-link&quot;&gt;https://github.com/Majkl578/doctrine-dbal/tree/DDC-1602&lt;/a&gt;&lt;br/&gt;
ORM branch with changes: &lt;a href=&quot;https://github.com/Majkl578/doctrine2/tree/DDC-1602&quot; class=&quot;external-link&quot;&gt;https://github.com/Majkl578/doctrine2/tree/DDC-1602&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Looking forward for your opinions.&lt;/p&gt;</comment>
                    <comment id="18148" author="majkl578" created="Wed, 27 Jun 2012 17:57:43 +0000"  >&lt;p&gt;bump&lt;/p&gt;</comment>
                </comments>
                    <attachments>
                </attachments>
            <subtasks>
        </subtasks>
        </item>
</channel>
</rss>