This is an automated email from the ASF dual-hosted git repository.

weizhou pushed a commit to branch 4.18
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/4.18 by this push:
     new 2cccd8f754a db: Add index on cluster_details.name for FirstFitPlanner 
speedup (#7922)
2cccd8f754a is described below

commit 2cccd8f754a17d49ca78920b8b62648d532b4cf0
Author: Marcus Sorensen <[email protected]>
AuthorDate: Thu Aug 31 13:43:23 2023 -0600

    db: Add index on cluster_details.name for FirstFitPlanner speedup (#7922)
---
 .../cloud/upgrade/dao/DatabaseAccessObject.java    | 29 +++++++++-
 .../java/com/cloud/upgrade/dao/DbUpgradeUtils.java |  8 +++
 .../com/cloud/upgrade/dao/Upgrade41800to41810.java |  5 ++
 .../upgrade/dao/DatabaseAccessObjectTest.java      | 61 ++++++++++++++++++++++
 4 files changed, 102 insertions(+), 1 deletion(-)

diff --git 
a/engine/schema/src/main/java/com/cloud/upgrade/dao/DatabaseAccessObject.java 
b/engine/schema/src/main/java/com/cloud/upgrade/dao/DatabaseAccessObject.java
index 21d5a205a09..0b38acb5c21 100644
--- 
a/engine/schema/src/main/java/com/cloud/upgrade/dao/DatabaseAccessObject.java
+++ 
b/engine/schema/src/main/java/com/cloud/upgrade/dao/DatabaseAccessObject.java
@@ -18,6 +18,7 @@ package com.cloud.upgrade.dao;
 
 import java.sql.Connection;
 import java.sql.PreparedStatement;
+import java.sql.ResultSet;
 import java.sql.SQLException;
 
 import org.apache.log4j.Logger;
@@ -84,6 +85,33 @@ public class DatabaseAccessObject {
         return columnExists;
     }
 
+    public String generateIndexName(String tableName, String columnName) {
+        return String.format("i_%s__%s", tableName, columnName);
+    }
+
+    public boolean indexExists(Connection conn, String tableName, String 
indexName) {
+        try (PreparedStatement pstmt = 
conn.prepareStatement(String.format("SHOW INDEXES FROM %s where Key_name = 
\"%s\"", tableName, indexName))) {
+            ResultSet result = pstmt.executeQuery();
+            if (result.next()) {
+                return true;
+            }
+        } catch (SQLException e) {
+            s_logger.debug(String.format("Index %s doesn't exist, ignoring 
exception:", indexName, e.getMessage()));
+        }
+        return false;
+    }
+
+    public void createIndex(Connection conn, String tableName, String 
columnName, String indexName) {
+        String stmt = String.format("CREATE INDEX %s on %s (%s)", indexName, 
tableName, columnName);
+        s_logger.debug("Statement: " + stmt);
+        try (PreparedStatement pstmt = conn.prepareStatement(stmt)) {
+            pstmt.execute();
+            s_logger.debug(String.format("Created index %s", indexName));
+        } catch (SQLException e) {
+            s_logger.warn(String.format("Unable to create index %s", 
indexName), e);
+        }
+    }
+
     protected static void closePreparedStatement(PreparedStatement pstmt, 
String errorMessage) {
         try {
             if (pstmt != null) {
@@ -93,5 +121,4 @@ public class DatabaseAccessObject {
             s_logger.warn(errorMessage, e);
         }
     }
-
 }
diff --git 
a/engine/schema/src/main/java/com/cloud/upgrade/dao/DbUpgradeUtils.java 
b/engine/schema/src/main/java/com/cloud/upgrade/dao/DbUpgradeUtils.java
index 02dad6250dc..6b4e1814de0 100644
--- a/engine/schema/src/main/java/com/cloud/upgrade/dao/DbUpgradeUtils.java
+++ b/engine/schema/src/main/java/com/cloud/upgrade/dao/DbUpgradeUtils.java
@@ -23,6 +23,14 @@ public class DbUpgradeUtils {
 
     private static DatabaseAccessObject dao = new DatabaseAccessObject();
 
+    public static void addIndexIfNeeded(Connection conn, String tableName, 
String columnName) {
+        String indexName = dao.generateIndexName(tableName, columnName);
+
+        if (!dao.indexExists(conn, tableName, indexName)) {
+            dao.createIndex(conn, tableName, columnName, indexName);
+        }
+    }
+
     public static void addForeignKey(Connection conn, String tableName, String 
tableColumn, String foreignTableName, String foreignColumnName) {
         dao.addForeignKey(conn, tableName, tableColumn, foreignTableName, 
foreignColumnName);
     }
diff --git 
a/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade41800to41810.java 
b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade41800to41810.java
index 8eb50666ec8..a58d9965259 100644
--- a/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade41800to41810.java
+++ b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade41800to41810.java
@@ -69,6 +69,7 @@ public class Upgrade41800to41810 implements DbUpgrade, 
DbUpgradeSystemVmTemplate
         copyGuestOsMappingsToVMware80u1();
         addForeignKeyToAutoscaleVmprofiles(conn);
         mergeDuplicateGuestOSes();
+        addIndexes(conn);
     }
 
     private void mergeDuplicateGuestOSes() {
@@ -242,4 +243,8 @@ public class Upgrade41800to41810 implements DbUpgrade, 
DbUpgradeSystemVmTemplate
     private void addForeignKeyToAutoscaleVmprofiles(Connection conn) {
         DbUpgradeUtils.addForeignKey(conn, "autoscale_vmprofiles", 
"user_data_id", "user_data", "id");
     }
+
+    private void addIndexes(Connection conn) {
+        DbUpgradeUtils.addIndexIfNeeded(conn, "cluster_details", "name");
+    }
 }
diff --git 
a/engine/schema/src/test/java/com/cloud/upgrade/dao/DatabaseAccessObjectTest.java
 
b/engine/schema/src/test/java/com/cloud/upgrade/dao/DatabaseAccessObjectTest.java
index 2b8b2bd8f1c..7e78c3ec3e9 100644
--- 
a/engine/schema/src/test/java/com/cloud/upgrade/dao/DatabaseAccessObjectTest.java
+++ 
b/engine/schema/src/test/java/com/cloud/upgrade/dao/DatabaseAccessObjectTest.java
@@ -16,6 +16,7 @@
 // under the License.
 package com.cloud.upgrade.dao;
 
+import static org.mockito.Matchers.startsWith;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.contains;
@@ -27,9 +28,11 @@ import static org.mockito.Mockito.when;
 
 import java.sql.Connection;
 import java.sql.PreparedStatement;
+import java.sql.ResultSet;
 import java.sql.SQLException;
 
 import org.apache.log4j.Logger;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -49,6 +52,9 @@ public class DatabaseAccessObjectTest {
     @Mock
     private Logger loggerMock;
 
+    @Mock
+    private ResultSet resultSetMock;
+
     private final DatabaseAccessObject dao = new DatabaseAccessObject();
 
     @Before
@@ -83,6 +89,61 @@ public class DatabaseAccessObjectTest {
         dao.dropKey(conn, tableName, key, isForeignKey);
     }
 
+    @Test
+    public void generateIndexNameTest() {
+        String indexName = dao.generateIndexName("mytable","mycolumn");
+        Assert.assertEquals( "i_mytable__mycolumn", indexName);
+    }
+
+    @Test
+    public void indexExistsFalseTest() throws Exception {
+        when(resultSetMock.next()).thenReturn(false);
+        when(connectionMock.prepareStatement(startsWith("SHOW INDEXES 
FROM"))).thenReturn(preparedStatementMock);
+        when(preparedStatementMock.executeQuery()).thenReturn(resultSetMock);
+
+        Connection conn = connectionMock;
+        String tableName = "mytable";
+        String indexName = "myindex";
+
+        Assert.assertFalse(dao.indexExists(conn, tableName, indexName));
+        verify(connectionMock, times(1)).prepareStatement(anyString());
+        verify(preparedStatementMock, times(1)).executeQuery();
+        verify(preparedStatementMock, times(1)).close();
+    }
+
+    @Test
+    public void indexExistsTrueTest() throws Exception {
+        when(resultSetMock.next()).thenReturn(true);
+        when(connectionMock.prepareStatement(startsWith("SHOW INDEXES 
FROM"))).thenReturn(preparedStatementMock);
+        when(preparedStatementMock.executeQuery()).thenReturn(resultSetMock);
+
+        Connection conn = connectionMock;
+        String tableName = "mytable";
+        String indexName = "myindex";
+
+        Assert.assertTrue(dao.indexExists(conn, tableName, indexName));
+        verify(connectionMock, times(1)).prepareStatement(anyString());
+        verify(preparedStatementMock, times(1)).executeQuery();
+        verify(preparedStatementMock, times(1)).close();
+    }
+
+    @Test
+    public void createIndexTest() throws Exception {
+        when(connectionMock.prepareStatement(startsWith("CREATE 
INDEX"))).thenReturn(preparedStatementMock);
+        when(preparedStatementMock.execute()).thenReturn(true);
+
+        Connection conn = connectionMock;
+        String tableName = "mytable";
+        String columnName = "mycolumn";
+        String indexName = "myindex";
+
+        dao.createIndex(conn, tableName, columnName, indexName);
+        verify(connectionMock, times(1)).prepareStatement(anyString());
+        verify(preparedStatementMock, times(1)).execute();
+        verify(preparedStatementMock, times(1)).close();
+        verify(loggerMock, times(1)).debug("Created index myindex");
+    }
+
     @Test
     public void testDropKeyWhenTableNameIsNull() throws Exception {
         SQLException sqlException = new SQLException();

Reply via email to