Мы рассматриваем возможность использования базы данных In-Memory (например, Apache Ignite) для выполнения интенсивных BI-подобных операций.В качестве (очень примитивного) примера я заполнил Apache Ignite 250 000 записей из csv-файла (14 столбцов) и выполнил некоторые операции группировки.Ранее я также использовал те же данные для некоторых тестов производительности с MS SQL-сервером.
Интересно и неожиданно, чтобы MS SQL-Server потребовалось около 0,25 секунды для выполнения этих операций, в то время как с Apache Ignite это занимает 1-2 секунды.
1, у меня всегда было впечатление, что Apache Ignite - это не только хороший вариант для распределенных вычислений, но также приводит к увеличению производительности по сравнению с обычной реляционной базой данных благодаря своей архитектуре, ориентированной на память.Это правда?Почему это медленно в моем примере?
2, я неправильно использовал Apache Ignite или есть какие-то дополнительные параметры настройки, которые мне следует использовать?
Вот исходный код, который я использовал в моем примере:
private static Connection conn = null;
private static Statement stmt = null;
private static ResultSet rs = null;
private static void initialize() throws ClassNotFoundException, SQLException
{
// Register JDBC driver.
Class.forName("org.apache.ignite.IgniteJdbcThinDriver");
// Create database tables.
stmt = conn.createStatement();
// Create table
stmt.executeUpdate("CREATE TABLE PIVOT_TEST (" +
" REGION VARCHAR, COUNTRY VARCHAR, ITEM_TYPE VARCHAR, SALES_CHANNEL VARCHAR, ORDER_PRIORITY VARCHAR, ORDER_DATE VARCHAR, ORDER_ID VARCHAR PRIMARY KEY, "
+ "SHIP_DATE VARCHAR, UNITS_SOLD NUMERIC, UNIT_PRICE NUMERIC, UNIT_COST NUMERIC, TOTAL_REVENUE NUMERIC, TOTAL_COST NUMERIC, TOTAL_PROFIT NUMERIC )");
}
private static void fill() throws ClassNotFoundException, SQLException
{
// Register JDBC driver
Class.forName("org.apache.ignite.IgniteJdbcThinDriver");
// Populate table
PreparedStatement stmt =
conn.prepareStatement("COPY FROM 'LINK_TO_CSV_FILE'" +
"INTO PIVOT_TEST (REGION , COUNTRY , ITEM_TYPE , SALES_CHANNEL , ORDER_PRIORITY , ORDER_DATE , ORDER_ID , SHIP_DATE , UNITS_SOLD , UNIT_PRICE , UNIT_COST , TOTAL_REVENUE , TOTAL_COST , TOTAL_PROFIT ) FORMAT CSV");
stmt.executeUpdate();
stmt = conn.prepareStatement("CREATE INDEX index_name ON PIVOT_TEST(COUNTRY)");
stmt.executeUpdate();
}
private static void getResult() throws ClassNotFoundException, SQLException
{
// Register JDBC driver
Class.forName("org.apache.ignite.IgniteJdbcThinDriver");
// Get data
stmt = conn.createStatement();
rs =
stmt.executeQuery("SELECT AVG(UNIT_PRICE) AS AVG_UNIT_PRICE, MAX(UNITS_SOLD) AS MAX_UNITS_SOLD, SUM(UNIT_COST) AS SUM_UNIT_COST, AVG(TOTAL_REVENUE) AS AVG_TOTAL_REVENUE , AVG(TOTAL_COST) AS AVG_TOTAL_COST, AVG(TOTAL_PROFIT) as AVG_TOTAL_PROFIT FROM PIVOT_TEST GROUP BY COUNTRY;");
retrieveResultSet();
}
private static void retrieveResultSet() throws SQLException
{
while (rs.next())
{
for(int i=0; i<rs.getMetaData().getColumnCount(); i++)
{
rs.getObject(i+1);
}
}
}
public static void main(String[] args) throws SQLException, ClassNotFoundException
{
Ignite ignite = null;
try
{
//--------------------------------CONNECTION-------------------//
IgniteConfiguration configuration = new IgniteConfiguration();
ignite = Ignition.start(configuration);
conn = DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1/");
initialize();
fill();
long endPrepTable = System.currentTimeMillis();
getResult();
long endGetResult = System.currentTimeMillis();
System.out.println("Get Result (s)" + " " + (endGetResult - endPrepTable)*1.0/1000);
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
ignite.close();
conn.close();
rs.close();
}
}
Спасибо за вашу помощь!