H2 Оптимизация выбора оператора / выключение дефрагментации - PullRequest
1 голос
/ 02 августа 2011

Контрольный пример:

drop table master;
create table master(id int primary key, fk1 int, fk2 int, fk3 int, dataS  varchar(255),    data1 int, data2 int, data3 int, data4 int,data5  int,data6 int,data7 int,data8 int,data9 int,b1 boolean,b2 boolean,b3 boolean,b4 boolean,b5 boolean,b6 boolean,b7 boolean,b8 boolean,b9 boolean,b10 boolean,b11 boolean,b12 boolean,b13 boolean,b14 boolean,b15 boolean,b16 boolean,b17 boolean,b18 boolean,b19 boolean,b20 boolean,b21 boolean,b22 boolean,b23 boolean,b24 boolean,b25 boolean,b26 boolean,b27 boolean,b28 boolean,b29 boolean,b30 boolean,b31 boolean,b32 boolean,b33 boolean,b34 boolean,b35 boolean,b36 boolean,b37 boolean,b38 boolean,b39 boolean,b40 boolean,b41 boolean,b42 boolean,b43 boolean,b44 boolean,b45 boolean,b46 boolean,b47 boolean,b48 boolean,b49 boolean,b50 boolean);

create index idx_comp on master(fk1,fk2,fk3);
@loop 5000000 insert into master values(?, mod(?,100), mod(?,5), ?,'Hello World Hello World Hello World',?, ?, ?,?, ?, ?, ?, ?, ?,true,true,true,true,true,true,false,false,false,true,true,true,true,true,true,true,false,false,false,true,true,true,true,true,true,true,false,false,false,true,true,true,true,true,true,true,false,false,false,true,true,true,true,true,true,true,false,false,false,true);

1. Следующий оператор выбора занимает до 30 секунд.Есть ли способ оптимизировать время отклика?

SELECT count(*), SUM(CONVERT(b1,INT)) ,SUM(CONVERT(b2,INT)),SUM(CONVERT(b3,INT)),SUM(CONVERT(b4,INT)),SUM(CONVERT(b5,INT)),SUM(CONVERT(b6,INT)),SUM(CONVERT(b7,INT)),SUM(CONVERT(b8,INT)),SUM(CONVERT(b9,INT)),SUM(CONVERT(b10,INT)),SUM(CONVERT(b11,INT)),SUM(CONVERT(b12,INT)),SUM(CONVERT(b13,INT)),SUM(CONVERT(b14,INT)),SUM(CONVERT(b15,INT)),SUM(CONVERT(b16,INT))
FROM  master
WHERE fk1=53 AND fk2=3

2.Я попытался отключить дефрагментацию.Но это утверждение заняло около 40 минут для моего теста.После выключения дефрагментации выбор занимает до 15 секунд.Если я выполню заявление снова, это займет менее 1 секунды.Даже если остановить и запустить сервер, инструкция занимает около 1 сек.Имеет ли H2 постоянный кэш?

Инфраструктура: WebBrowser <-> Консольный сервер H2 <-> H2 DB: h2 1.3.158

Ответы [ 2 ]

2 голосов
/ 02 августа 2011

Согласно выводу профилировщика, основная проблема (93%) - чтение с диска.Я запустил это в консоли H2:

@prof_start;
SELECT ... FROM  master WHERE fk1=53 AND fk2=3;
@prof_stop;

и получил:

Profiler: top 3 stack trace(s) of 48039 ms [build-158]:
4084/4376 (93%):
at java.io.RandomAccessFile.readBytes(Native Method)
at java.io.RandomAccessFile.read(RandomAccessFile.java:338)
at java.io.RandomAccessFile.readFully(RandomAccessFile.java:397)
at org.h2.store.FileStore.readFully(FileStore.java:285)
at org.h2.store.PageStore.readPage(PageStore.java:1253)
at org.h2.store.PageStore.getPage(PageStore.java:707)
at org.h2.index.PageDataIndex.getPage(PageDataIndex.java:225)
at org.h2.index.PageDataNode.getRowWithKey(PageDataNode.java:269)
at org.h2.index.PageDataNode.getRowWithKey(PageDataNode.java:270)

Согласно EXPLAIN ANALYZE SELECT он читает более 55'000 страниц с диска (по 2 КБ на страницу;110 МБ) по этому запросу.Я не уверен, как другие базы данных работают для такого запроса.Но я думаю, если возможно, запрос должен быть изменен так, чтобы он читал меньше данных.

1 голос
/ 02 августа 2011

Возможно ли иметь временную таблицу / представление, в которой уже выполнены преобразования типов данных? Если возможно, что это обновление будет происходить из основной таблицы время от времени (раз в ночь или около того), то у вас уже есть много вычислительной мощности, которая уже включена в преобразование.

Если это невозможно, вы можете сделать несколько подвыборов, по одному для каждого столбца "b", где вы тянете только где b # = 1. Затем выполните СЧЕТ вместо СУММЫ, которая также должна быть быстрее , Например:

SELECT (count1+count2) AS Count, 
(SELECT COUNT(*) FROM master WHERE fk1=53 AND fk2=3 AND b1=1) AS count1
(SELECT COUNT(*) FROM master  WHERE fk1=53 AND fk2=3 AND b2=1) AS count2

Я не уверен, что этот точный синтаксис работает в вашей программе, но, надеюсь, в качестве общей идеи SQL он выведет вас на правильный путь.

...