mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
db: Add index on cluster_details.name for FirstFitPlanner speedup (#7922)
This commit is contained in:
parent
439d70fd2b
commit
2cccd8f754
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@ -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();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user