[Rt-commit] rt branch, 4.2/is-merged-column, created. rt-4.1.6-344-gde65677

Ruslan Zakirov ruz at bestpractical.com
Tue Mar 12 15:25:32 EDT 2013


The branch, 4.2/is-merged-column has been created
        at  de656773973956a3f2a143a711a85514c5bb3506 (commit)

- Log -----------------------------------------------------------------
commit de656773973956a3f2a143a711a85514c5bb3506
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Mon Dec 5 21:40:45 2011 +0400

    add IsMerged boolean column to reflect id != EffectiveId
    
    Most of queries on Tickets has id == EffectiveId condition
    that is required to skip merged tickets. Usually percentage
    of merged tickets is very low, so this condition is true.
    However, DBs like Pg and Oracle estimate number of returned
    records very wrong. Each column is very distinct and statisticly
    speaking chance that one record has the same value in id and
    EffectiveId is low, but this is only true when correlation
    is not accounted and it's not accounted in mentioned DBs.
    
    We add IsMerged column with "boolean" type that reflects
    id != EffectiveId. It fixes estimations of DB optimizers.
    Query execution plans get better.
    
    Instead of adding the column we could use NULLs in EffectiveId
    for records where now id = EffectiveId, but this means ORed
    conditions in JOIN clause for rare queries. Tests show that
    such solution result in terrible perfomance degradation on
    mysql in these rare situations.

diff --git a/etc/schema.Oracle b/etc/schema.Oracle
index 52ce347..24849d1 100755
--- a/etc/schema.Oracle
+++ b/etc/schema.Oracle
@@ -261,6 +261,7 @@ CREATE TABLE Tickets (
        id                      NUMBER(11, 0) 
                CONSTRAINT Tickets_Key PRIMARY KEY,
         EffectiveId             NUMBER(11,0) DEFAULT 0 NOT NULL,
+  	IsMerged 		NUMBER(11,0) DEFAULT NULL NULL,
         Queue                   NUMBER(11,0) DEFAULT 0 NOT NULL,
         Type                    VARCHAR2(16),           
         IssueStatement          NUMBER(11,0) DEFAULT 0 NOT NULL,
diff --git a/etc/schema.Pg b/etc/schema.Pg
index dfb5557..b0f9662 100755
--- a/etc/schema.Pg
+++ b/etc/schema.Pg
@@ -414,6 +414,7 @@ CREATE SEQUENCE tickets_id_seq;
 CREATE TABLE Tickets (
   id INTEGER DEFAULT nextval('tickets_id_seq'),
   EffectiveId integer NOT NULL DEFAULT 0  ,
+  IsMerged smallint NULL DEFAULT NULL ,
   Queue integer NOT NULL DEFAULT 0  ,
   Type varchar(16) NULL  ,
   IssueStatement integer NOT NULL DEFAULT 0  ,
diff --git a/etc/schema.SQLite b/etc/schema.SQLite
index 4d0f12e..a10a845 100755
--- a/etc/schema.SQLite
+++ b/etc/schema.SQLite
@@ -285,6 +285,7 @@ CREATE INDEX Users4 ON Users (EmailAddress);
 CREATE TABLE Tickets (
   id INTEGER PRIMARY KEY  ,
   EffectiveId integer NULL DEFAULT 0 ,
+  IsMerged int2 NULL DEFAULT NULL,
   Queue integer NULL DEFAULT 0 ,
   Type varchar(16) NULL  ,
   IssueStatement integer NULL DEFAULT 0 ,
diff --git a/etc/schema.mysql b/etc/schema.mysql
index ab81be4..bed471e 100755
--- a/etc/schema.mysql
+++ b/etc/schema.mysql
@@ -272,6 +272,7 @@ CREATE INDEX Users4 ON Users (EmailAddress);
 CREATE TABLE Tickets (
   id INTEGER NOT NULL  AUTO_INCREMENT,
   EffectiveId integer NOT NULL DEFAULT 0  ,
+  IsMerged int2 NULL DEFAULT NULL,
   Queue integer NOT NULL DEFAULT 0  ,
   Type varchar(16) CHARACTER SET ascii NULL  ,
   IssueStatement integer NOT NULL DEFAULT 0  ,
diff --git a/etc/upgrade/4.1.8/schema.Oracle b/etc/upgrade/4.1.8/schema.Oracle
new file mode 100644
index 0000000..6f2d962
--- /dev/null
+++ b/etc/upgrade/4.1.8/schema.Oracle
@@ -0,0 +1,2 @@
+ALTER TABLE Tickets ADD IsMerged NUMBER(11,0) DEFAULT NULL NULL,
+UPDATE Tickets SET IsMerged = 1 WHERE id != EffectiveId;
diff --git a/etc/upgrade/4.1.8/schema.Pg b/etc/upgrade/4.1.8/schema.Pg
new file mode 100644
index 0000000..a35287e
--- /dev/null
+++ b/etc/upgrade/4.1.8/schema.Pg
@@ -0,0 +1,2 @@
+ALTER TABLE Tickets ADD COLUMN IsMerged smallint NULL DEFAULT NULL;
+UPDATE Tickets SET IsMerged = 1 WHERE id != EffectiveId;
diff --git a/etc/upgrade/4.1.8/schema.SQLite b/etc/upgrade/4.1.8/schema.SQLite
new file mode 100644
index 0000000..4e28e3b
--- /dev/null
+++ b/etc/upgrade/4.1.8/schema.SQLite
@@ -0,0 +1,3 @@
+ALTER TABLE Tickets ADD COLUMN IsMerged int2 NULL DEFAULT NULL;
+UPDATE Tickets SET IsMerged = 1 WHERE id != EffectiveId;
+
diff --git a/etc/upgrade/4.1.8/schema.mysql b/etc/upgrade/4.1.8/schema.mysql
new file mode 100644
index 0000000..8977c10
--- /dev/null
+++ b/etc/upgrade/4.1.8/schema.mysql
@@ -0,0 +1,2 @@
+ALTER TABLE Tickets ADD COLUMN IsMerged int2 NULL DEFAULT NULL;
+UPDATE Tickets SET IsMerged = 1 WHERE id != EffectiveId;
diff --git a/lib/RT/Ticket.pm b/lib/RT/Ticket.pm
index b5eff48..a01b70c 100644
--- a/lib/RT/Ticket.pm
+++ b/lib/RT/Ticket.pm
@@ -1857,6 +1857,11 @@ sub _MergeInto {
         return ( 0, $self->loc("Merge failed. Couldn't set EffectiveId") );
     }
 
+    ( $id_val, $id_msg ) = $self->__Set( Field => 'IsMerged', Value => 1 );
+    unless ($id_val) {
+        $RT::Handle->Rollback();
+        return ( 0, $self->loc("Merge failed. Couldn't set IsMerged") );
+    }
 
     my $force_status = $self->LifecycleObj->DefaultOnMerge;
     if ( $force_status && $force_status ne $self->__Value('Status') ) {
@@ -3362,6 +3367,8 @@ sub _CoreAccessible {
                 {read => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => ''},
         EffectiveId =>
                 {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
+        IsMerged =>
+		{read => 1, write => 1, sql_type => 5, length => 6,  is_blob => 0,  is_numeric => 1,  type => 'smallint(6)', default => undef},
         Queue =>
                 {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Type =>
diff --git a/lib/RT/Tickets.pm b/lib/RT/Tickets.pm
index 6c81505..9f19c74 100644
--- a/lib/RT/Tickets.pm
+++ b/lib/RT/Tickets.pm
@@ -3384,9 +3384,11 @@ sub FromSQL {
 
     # We only want to look at EffectiveId's (mostly) for these searches.
     unless ( $self->{_sql_looking_at}{effectiveid} ) {
+        # instead of EffectiveId = id we do IsMerged IS NULL
         $self->Limit(
-            FIELD           => 'EffectiveId',
-            VALUE           => 'main.id',
+            FIELD           => 'IsMerged',
+            OPERATOR        => 'IS',
+            VALUE           => 'NULL',
             ENTRYAGGREGATOR => 'AND',
             QUOTEVALUE      => 0,
         );

-----------------------------------------------------------------------


More information about the Rt-commit mailing list