В ваших скриптах инициализации есть синтаксические ошибки, я изменил их следующим образом:
CREATE TABLE A(
id int not null primary key,
groupby int null,
fkb int null,
search int null,
padding varchar(1000) null
) AS
SELECT cast(x as int) id,
cast(mod(x, 100) as int) groupby,
cast(mod(mod(x, 100), 9173) as int) fkb,
cast(mod(x, 911) as int) search,
rpad(concat('Value ', x), 1000, '*') as padding
FROM SYSTEM_RANGE(0, 999999);
CREATE TABLE B(
id int not null primary key,
groupby int null,
search int null
) AS
SELECT cast(x as int) id,
cast(mod(x + floor(100000 / (x+1)), 100) as int) groupby,
cast(mod(x, 901) as int) search
FROM SYSTEM_RANGE(0, 9999);
Для простоты я также использовал специфический для H2 SYSTEM_RANGE()
.
Команда EXPLAIN с вашим запросом показывает следующий план выполнения
SELECT
"B"."GROUPBY",
COUNT(CASE WHEN ("A"."SEARCH" = 1) THEN 1 END) AS "SEARCH1",
COUNT(CASE WHEN ("A"."SEARCH" = 900) THEN 1 END) AS "SEARCH2"
FROM "PUBLIC"."B"
/* PUBLIC.B.tableScan */
/* WHERE B.SEARCH < 10
*/
LEFT OUTER JOIN "PUBLIC"."A"
/* PUBLIC.A.tableScan */
ON "A"."FKB" = "B"."ID"
WHERE "B"."SEARCH" < 10
GROUP BY "B"."GROUPBY"
Это ожидается, потому что у вас нет индексов. К сожалению, вы не можете значительно улучшить производительность без них.
Я думаю, вам нужно здесь ограничение.
ALTER TABLE A ADD CONSTRAINT A_FKB_FK FOREIGN KEY(FKB) REFERENCES B(ID);
С таким ограничением план выполнения намного лучше:
SELECT
"B"."GROUPBY",
COUNT(CASE WHEN ("A"."SEARCH" = 1) THEN 1 END) AS "SEARCH1",
COUNT(CASE WHEN ("A"."SEARCH" = 900) THEN 1 END) AS "SEARCH2"
FROM "PUBLIC"."B"
/* PUBLIC.B.tableScan */
/* WHERE B.SEARCH < 10
*/
LEFT OUTER JOIN "PUBLIC"."A"
/* PUBLIC.A_FKB_FK_INDEX_4: FKB = B.ID */
ON "A"."FKB" = "B"."ID"
WHERE "B"."SEARCH" < 10
GROUP BY "B"."GROUPBY"
С ограничением ваш запрос требует около 11 секунд на моем старом ПК.
Вы также можете использовать COUNT(*) FILTER (WHERE A.search = 1)
в своем запросе с H2, но такой запрос не будет совместим с MySQL, MySQL пока не поддерживает стандартное предложение FILTER для SQL: 2003, а предложение FILTER на самом деле не повышает производительность этот запрос обеспечивает лучшую читаемость.