Uploaded image for project: 'Jira Data Center'
  1. Jira Data Center
  2. JRASERVER-63002

Create new composite indexes for changegroup and changeitem tables to improve performance

    • 6.04
    • 94
    • Severity 3 - Minor
    • 158
    • Hide
      Atlassian Update – 01 February 2019

      Hello everyone,

      We introduced indexes to changegroup and changeitem tables.
      The new indexes are named chggroup_issue_id and chgitem_group_field. If you modified your indexes please adjust names/remove them. Otherwise they will get duplicated.

      As a friendly reminder - remember to update your database statistics frequently. Otherwise your queries will be vulnerable to parameter sniffing.

      Sincerely,
      Jira Bugfix Team.

      Show
      Atlassian Update – 01 February 2019 Hello everyone, We introduced indexes to changegroup and changeitem tables. The new indexes are named chggroup_issue_id and chgitem_group_field. If you modified your indexes please adjust names/remove them. Otherwise they will get duplicated. As a friendly reminder - remember to update your database statistics frequently. Otherwise your queries will be vulnerable to parameter sniffing. Sincerely, Jira Bugfix Team.

      Issue Summary

      Improve database indexes for changeitem and changegroup tables.

      Steps to Reproduce

      1. Have a Jira instance with a large number of issues, with heavy Agile usage.

      Expected Results

      Jira performance remains as usual.

      Actual Results

      Jira performance decreases greatly.

      Notes

      • The default indexes on both tables are as illustrated in the following screenshots:
        Table changeitem

        table changegroup
      • Based on users's DBA findings from their database monitoring, there's a high and troublesome CPU impact of the following query:
        SELECT CG.ID, CG.issueid, CG.AUTHOR, CG.CREATED, CI.ID, CI.groupid, CI.FIELDTYPE,
        CI.FIELD, CI.OLDVALUE, CI.OLDSTRING, CI.NEWVALUE, CI.NEWSTRING
         FROM changegroup CG INNER JOIN
         changeitem CI ON CG.ID = CI.groupid
         WHERE CG.issueid=:1 AND CI.FIELD=:2
        ORDER BY CG.CREATED ASC, CI.ID ASC
        

        This is understandable as JIRA retrieves change history for rendering issue history tabs and JIRA Agile reports. However the DBA was able to significantly improve the performance by creating 2 new indexes:

        CREATE UNIQUE INDEX JIRADBUSER.CHANGEGROUP_SCX1
         ON JIRADBUSER.CHANGEGROUP
        (ISSUEID, ID)
        TABLESPACE JIRA_DATA;
        
        CREATE INDEX JIRADBUSER.CHANGEITEM_SCX1
         ON JIRADBUSER.CHANGEITEM
         (GROUPID, FIELD)
        TABLESPACE JIRA_DATA;
        

        which is believed to improve the performance considerably. We are assuming the logic behind this is the join on changegroup.id <==> changeitem.groupid Please consider the following arguments from the user:

      Workaround

      Note: Always back up your data before performing any modifications to the database. If possible, test any alter, insert, update, or delete SQL commands on a staging server first.

      Adding the indexes mentioned before seems to alleviate the problem.

        1. Feedback DBA Securex.pdf
          277 kB
        2. Selection_198.jpg
          Selection_198.jpg
          27 kB
        3. Selection_199.jpg
          Selection_199.jpg
          36 kB
        4. v$sqlstats_After_Drop_Indexes.xlsx
          19 kB
        5. v$sqlstats_Before_Drop_Indexes.xlsx
          14 kB

            [JRASERVER-63002] Create new composite indexes for changegroup and changeitem tables to improve performance

            Gaj Umapathy added a comment - - edited

            We had this issue on Jira 7.13.8 and we applied the indexes. This has made a huge difference to the database usage. We are on Azure SQL PaaS.

             

            -- 1st Index 
            CREATE UNIQUE INDEX chggroup_issue_id
             ON dbo.changegroup
            (issueid, ID)
            
            -- 2nd index 
            
            CREATE INDEX chgitem_group_field
             ON dbo.changeitem
             (groupid, FIELD)
            
             -- update statistics on both tables where index was added
            
              UPDATE STATISTICS dbo.changegroup
            
              UPDATE STATISTICS dbo.changeitem
            

            Gaj Umapathy added a comment - - edited We had this issue on Jira 7.13.8 and we applied the indexes. This has made a huge difference to the database usage. We are on Azure SQL PaaS.   -- 1st Index CREATE UNIQUE INDEX chggroup_issue_id ON dbo.changegroup (issueid, ID) -- 2nd index CREATE INDEX chgitem_group_field ON dbo.changeitem (groupid, FIELD) -- update statistics on both tables where index was added UPDATE STATISTICS dbo.changegroup UPDATE STATISTICS dbo.changeitem

            Adrian Stephen added a comment - - edited

            If you are still facing this issue post-JIRA 8.0, it is most likely that additional indices IX_changegroup$issueid$iD$created and IX_changeitem$FIELD$GROUPID which were set up previously and not removed before upgrading to JIRA 8.00 or later. This will interfere with change introduced in this bug fix JRASERVER-63002.

            Resolution

            Ensure that IX_changegroup$issueid$iD$created and IX_changeitem$FIELD$GROUPID are dropped.

            Thanks to kkolonko for this.

            Adrian Stephen added a comment - - edited If you are still facing this issue post-JIRA 8.0, it is most likely that additional indices IX_changegroup$issueid$iD$created and IX_changeitem$FIELD$GROUPID which were set up previously and not removed before upgrading to JIRA 8.00 or later. This will interfere with change introduced in this bug fix JRASERVER-63002 . Resolution Ensure that IX_changegroup$issueid$iD$created and IX_changeitem$FIELD$GROUPID are dropped. Thanks to kkolonko for this.

            Hello!

            Thanks, we are waiting this improvement for our setup from out-of-the-box
            Also, please, add affected version the 7.6.10 release.

            Cheers,
            Gonchik Tsymzhitov

            Gonchik Tsymzhitov added a comment - Hello! Thanks, we are waiting this improvement for our setup from out-of-the-box Also, please, add affected version the 7.6.10 release. Cheers, Gonchik Tsymzhitov

            Hello, everyone! In an effort to keep bug reports up to date, we have verified the behavior indicated here and have updated the affected versions as well as cleaned up the format of the summary to increase its SEO and to be aligned with our current guidelines. In case there is any additional technical information that you consider important for this case, feel free to add a comment with it.

            Best regards,
            René Chiquete - JAC Champion.

            Rene C. [Atlassian Support] added a comment - Hello, everyone! In an effort to keep bug reports up to date, we have verified the behavior indicated here and have updated the affected versions as well as cleaned up the format of the summary to increase its SEO and to be aligned with our current guidelines. In case there is any additional technical information that you consider important for this case, feel free to add a comment with it. Best regards, René Chiquete - JAC Champion.

            We experience this problem in production where the query above last over seconds. Creating the described indexes improved performance dramatically. The query is no longer listed in active expensive queries.

            Deleted Account (Inactive) added a comment - We experience this problem in production where the query above last over seconds. Creating the described indexes improved performance dramatically. The query is no longer listed in active expensive queries.

            tony_chu
            I'm happy to hear that.
            Just keep in mind that after we publish fix, 
            it will be nice to perform xml import on clean database,
            so no redundant indexes get left behind,
            OR you will need to remove them before update.

            ΞΔ (Inactive) added a comment - tony_chu I'm happy to hear that. Just keep in mind that after we publish fix,  it will be nice to perform xml import on clean database, so no redundant indexes get left behind, OR you will need to remove them before update.

            Tony Chu added a comment - - edited

            Hi psuwala,

            This is an update about our finding (on our staging server).
            To conduct the test, we use the "re-index" feature. This is because we know it will generally take a long time to traverse all issues and update the data (from SQL Server) to its own indexes. We have many Scripted Fields which generate their result on-the-fly, many of which are using the data from change history. So, re-indexing will actually pull the data from change history quite intensively, ideal for our test purpose. The following is the result: (the time is our local time GMT+8)

            Original: Keeping the original indexes without adding new ones

            1. (Background re-index)
              • Start: 12:44:00
              • Stop: 12:55:09
              • Elapsed: 11:09
              • CPU: 30%~40%
            2. (Lock JIRA and rebuild index)
              • Start: 12:56:00
              • Stop: 12:58:05
              • Elapsed: 2:05
              • CPU: 80%~90%
            3. (Lock JIRA and rebuild index)
              • Start: 12:59:00
              • Stop: 13:01:05
              • Elapsed: 2:05
              • CPU: 80%~90%

            Use the suggestion: Add the 2 new indexes and disable INDEX chgitem_field ON dbo.changeitem

            1. (Background re-index)
              • Start: 13:09:00
              • Stop: 13:13:15
              • Elapsed: 4:15
              • CPU: 10%~20%
            2. (Lock JIRA and rebuild index)
              • Start: 13:14:00
              • Stop: 13:15:17
              • Elapsed: 1:17
              • CPU: 40%~60%
            3. (Lock JIRA and rebuild index)
              • Start: 13:16:00
              • Stop: 13:17:14
              • Elapsed: 1:14
              • CPU: 50%~70%

            Although we don't have many data on staging server (only 3,300+ of them), the effect of applying the new indexes (and disabling the old one) is still quite prominent nevertheless. Thus. we will adopt the new indexes, but we also will keep the old one just for safety measure.
            Thank you!

            Tony Chu added a comment - - edited Hi  psuwala , This is an update about our finding (on our staging server). To conduct the test, we use the "re-index" feature. This is because we know it will generally take a long time to traverse all issues and update the data (from SQL Server) to its own indexes. We have many Scripted Fields which generate their result on-the-fly, many of which are using the data from change history. So, re-indexing will actually pull the data from change history quite intensively, ideal for our test purpose. The following is the result: (the time is our local time GMT+8) Original: Keeping the original indexes without adding new ones (Background re-index) Start: 12:44:00 Stop: 12:55:09 Elapsed: 11:09 CPU: 30%~40% (Lock JIRA and rebuild index) Start: 12:56:00 Stop: 12:58:05 Elapsed: 2:05 CPU: 80%~90% (Lock JIRA and rebuild index) Start: 12:59:00 Stop: 13:01:05 Elapsed: 2:05 CPU: 80%~90% Use the suggestion: Add the 2 new indexes and disable INDEX chgitem_field ON dbo.changeitem (Background re-index) Start: 13:09:00 Stop: 13:13:15 Elapsed: 4:15 CPU: 10%~20% (Lock JIRA and rebuild index) Start: 13:14:00 Stop: 13:15:17 Elapsed: 1:17 CPU: 40%~60% (Lock JIRA and rebuild index) Start: 13:16:00 Stop: 13:17:14 Elapsed: 1:14 CPU: 50%~70% Although we don't have many data on staging server (only 3,300+ of them), the effect of applying the new indexes (and disabling the old one) is still quite prominent nevertheless. Thus. we will adopt the new indexes, but we also will keep the old one just for safety measure. Thank you!

            Tony Chu added a comment - - edited

            Hi Piotr,

            I'm guessing you want us to add the 2 indexes again (because we dropped them the other day when we discovered they didn't help):

            CREATE NONCLUSTERED INDEX [changegroup_issueid_ID] ON [dbo].[changegroup] (
            [issueid] ASC, [ID] ASC
            );

            CREATE NONCLUSTERED INDEX [changeitem_groupid_FIELD] ON [dbo].[changeitem] (
            [groupid] ASC, [FIELD] ASC
            );

            And then disable this one which is from default JIRA installation:

            CREATE NONCLUSTERED INDEX [chgitem_field] ON [dbo].[changeitem](
            [FIELD] ASC
            );

            It would be nice if we can try your idea, which is a good QA approach, by the way. However, we cannot do that.

            • This is a production system. Many of our support teams (around the globe from different regions) face the pressure from our customers so they cannot afford the system down time. Namely, if it (ever) happens again in a short period of time (like, in just a week), my team is to blame. Currently we prefer to avoid any risk.
            • We have asked IT team to raise the virtual processors from 4 to 8. Now the CPU chart is really low (around 5%, give or take). I have a feeling that switching the use of the new index might not make any noticeable difference. Unless we downgrade the system to use 4 virtual processors again... But, I'm afraid it's not my call. (guess who will not approve it?)

            The only possible way to test is do it on our test/staging server, which still has only 2 virtual processors. However, this server has much less issues data on it, so I'm not sure it can re-create the symptom. I will keep you posted if we discover anything.

            Tony Chu added a comment - - edited Hi Piotr, I'm guessing you want us to add the 2 indexes again (because we dropped them the other day when we discovered they didn't help): CREATE NONCLUSTERED INDEX [changegroup_issueid_ID] ON [dbo] . [changegroup] ( [issueid] ASC, [ID] ASC ); CREATE NONCLUSTERED INDEX [changeitem_groupid_FIELD] ON [dbo] . [changeitem] ( [groupid] ASC, [FIELD] ASC ); And then disable this one which is from default JIRA installation: CREATE NONCLUSTERED INDEX [chgitem_field] ON [dbo] . [changeitem] ( [FIELD] ASC ); It would be nice if we can try your idea, which is a good QA approach, by the way. However, we cannot do that. This is a production system. Many of our support teams (around the globe from different regions) face the pressure from our customers so they cannot afford the system down time. Namely, if it (ever) happens again in a short period of time (like, in just a week), my team is to blame. Currently we prefer to avoid any risk. We have asked IT team to raise the virtual processors from 4 to 8. Now the CPU chart is really low (around 5%, give or take). I have a feeling that switching the use of the new index might not make any noticeable difference. Unless we downgrade the system to use 4 virtual processors again... But, I'm afraid it's not my call. (guess who will not approve it?) The only possible way to test is do it on our test/staging server, which still has only 2 virtual processors. However, this server has much less issues data on it, so I'm not sure it can re-create the symptom. I will keep you posted if we discover anything.

            ΞΔ (Inactive) added a comment - - edited

            tony_chu  zafer

            These two new indexes were made in fact to prefer nested loops over hash join.
            You can try to disable temporarly field index on changeitem table to see if it helps,
            but only if you created these two indexes beforehand.
            It could be a great help for us, because as we know hash join on small instances is still faster choice and we are having argument if removing field index is surely good path to go.

            ΞΔ (Inactive) added a comment - - edited tony_chu   zafer These two new indexes were made in fact to prefer nested loops over hash join. You can try to disable temporarly field index on changeitem table to see if it helps, but only if you created these two indexes beforehand. It could be a great help for us, because as we know hash join on small instances is still faster choice and we are having argument if removing field index is surely good path to go.

            Thanks Tony for additional info.

            We've exact same problem and looking for workarounds. It's good to know that increasing CPU "solved" this problem. We'll try this.

            Zafer Cakmak added a comment - Thanks Tony for additional info. We've exact same problem and looking for workarounds. It's good to know that increasing CPU "solved" this problem. We'll try this.

              psuwala ΞΔ (Inactive)
              astephen@atlassian.com Adrian Stephen
              Affected customers:
              60 This affects my team
              Watchers:
              102 Start watching this issue

                Created:
                Updated:
                Resolved: