У меня были проблемы с именованным запросом в Java , но проблема заключалась в том, что проблема была во H2.
Я думал, что ANALYZE
было моим решением и решило бы мою проблему. Это было сделано локально на моей машине разработчика. На стороне клиента это только ухудшило ситуацию.
Сценарий:
У меня есть база данных H2 с данными версии 105. После импорта еще нескольких данных она становится версией 106.
Стол выглядит так
Запрос (получить строки с заданным guid, локальной и самой высокой версией):
SELECT tdo.TECDOC_GUID as guid, tdo.TECDOC_LOCALE as locale , tdo.TECDOC_VERSION as version, tdo.DATA as data
FROM TECDOC_OBJECTS tdo
LEFT OUTER JOIN TECDOC_OBJECTS tdo1
ON (
tdo.TECDOC_GUID = tdo1.TECDOC_GUID AND
tdo.TECDOC_LOCALE = tdo1.TECDOC_LOCALE AND
tdo.TECDOC_VERSION < tdo1.TECDOC_VERSION)
WHERE tdo1.id IS NULL
AND tdo.TECDOC_GUID in ('GUID-F2F77CE5-D8F5-4286-9A30-8FD500F735F6', 'GUID-41FD28DC-63C0-44D0-B8AE-0FCF7C78CEB0')
AND tdo.TECDOC_LOCALE = 'de';
До того, как я запустил команду ANALYZE
, план выполнения (scanCount действительно низкий):
SELECT
TDO.TECDOC_GUID AS GUID,
TDO.TECDOC_LOCALE AS LOCALE,
TDO.TECDOC_VERSION AS VERSION,
TDO.DATA AS DATA
FROM PUBLIC.TECDOC_OBJECTS TDO
/* PUBLIC.IDX_TECDOC_GUID: TECDOC_GUID IN('GUID-F2F77CE5-D8F5-4286-9A30-8FD500F735F6', 'GUID-41FD28DC-63C0-44D0-B8AE-0FCF7C78CEB0') */
/* WHERE (TDO.TECDOC_GUID IN('GUID-F2F77CE5-D8F5-4286-9A30-8FD500F735F6', 'GUID-41FD28DC-63C0-44D0-B8AE-0FCF7C78CEB0'))
AND (TDO.TECDOC_LOCALE = 'de')
*/
/* scanCount: 19 */
LEFT OUTER JOIN PUBLIC.TECDOC_OBJECTS TDO1
/* PUBLIC.IDX_GUID_LOCALE_VERSION: TECDOC_GUID = TDO.TECDOC_GUID
AND TECDOC_LOCALE = TDO.TECDOC_LOCALE
AND TECDOC_VERSION > TDO.TECDOC_VERSION
*/
ON (TDO.TECDOC_VERSION < TDO1.TECDOC_VERSION)
AND ((TDO.TECDOC_GUID = TDO1.TECDOC_GUID)
AND (TDO.TECDOC_LOCALE = TDO1.TECDOC_LOCALE))
/* scanCount: 4 */
WHERE (TDO.TECDOC_LOCALE = 'de')
AND ((TDO.TECDOC_GUID IN('GUID-F2F77CE5-D8F5-4286-9A30-8FD500F735F6', 'GUID-41FD28DC-63C0-44D0-B8AE-0FCF7C78CEB0'))
AND (TDO1.ID IS NULL))
/*
total: 37
TECDOC_OBJECTS.IDX_GUID_LOCALE_VERSION read: 6 (16%)
TECDOC_OBJECTS.IDX_TECDOC_GUID read: 8 (21%)
TECDOC_OBJECTS.TECDOC_OBJECTS_DATA read: 23 (62%)
*/
SELECT
TDO.TECDOC_GUID AS GUID,
TDO.TECDOC_LOCALE AS LOCALE,
TDO.TECDOC_VERSION AS VERSION,
TDO.DATA AS DATA
FROM PUBLIC.TECDOC_OBJECTS TDO
/* PUBLIC.IDX_GUID_LOCALE_VERSION: TECDOC_LOCALE = 'de'
AND TECDOC_GUID IN('GUID-F2F77CE5-D8F5-4286-9A30-8FD500F735F6', 'GUID-41FD28DC-63C0-44D0-B8AE-0FCF7C78CEB0')
*/
/* WHERE (TDO.TECDOC_GUID IN('GUID-F2F77CE5-D8F5-4286-9A30-8FD500F735F6', 'GUID-41FD28DC-63C0-44D0-B8AE-0FCF7C78CEB0'))
AND (TDO.TECDOC_LOCALE = 'de')
*/
/* scanCount: 287385 */
LEFT OUTER JOIN PUBLIC.TECDOC_OBJECTS TDO1
/* PUBLIC.IDX_GUID_LOCALE_VERSION: TECDOC_GUID = TDO.TECDOC_GUID
AND TECDOC_LOCALE = TDO.TECDOC_LOCALE
AND TECDOC_VERSION > TDO.TECDOC_VERSION
*/
ON (TDO.TECDOC_VERSION < TDO1.TECDOC_VERSION)
AND ((TDO.TECDOC_GUID = TDO1.TECDOC_GUID)
AND (TDO.TECDOC_LOCALE = TDO1.TECDOC_LOCALE))
/* scanCount: 4 */
WHERE (TDO.TECDOC_LOCALE = 'de')
AND ((TDO.TECDOC_GUID IN('GUID-F2F77CE5-D8F5-4286-9A30-8FD500F735F6', 'GUID-41FD28DC-63C0-44D0-B8AE-0FCF7C78CEB0'))
AND (TDO1.ID IS NULL))
/*
total: 11891
TECDOC_OBJECTS.IDX_GUID_LOCALE_VERSION read: 11884 (99%)
TECDOC_OBJECTS.TECDOC_OBJECTS_DATA read: 7 (0%)
*/
После того, как я запустил команду ANALYZE
, план выполнения (scanCount действительно высокий):
SELECT
TDO.TECDOC_GUID AS GUID,
TDO.TECDOC_LOCALE AS LOCALE,
TDO.TECDOC_VERSION AS VERSION,
TDO.DATA AS DATA
FROM PUBLIC.TECDOC_OBJECTS TDO
/* PUBLIC.IDX_GUID_LOCALE_VERSION: TECDOC_LOCALE = 'de'
AND TECDOC_GUID IN('GUID-F2F77CE5-D8F5-4286-9A30-8FD500F735F6', 'GUID-41FD28DC-63C0-44D0-B8AE-0FCF7C78CEB0')
*/
/* WHERE (TDO.TECDOC_GUID IN('GUID-F2F77CE5-D8F5-4286-9A30-8FD500F735F6', 'GUID-41FD28DC-63C0-44D0-B8AE-0FCF7C78CEB0'))
AND (TDO.TECDOC_LOCALE = 'de')
*/
/* scanCount: 287385 */
LEFT OUTER JOIN PUBLIC.TECDOC_OBJECTS TDO1
/* PUBLIC.IDX_GUID_LOCALE_VERSION: TECDOC_GUID = TDO.TECDOC_GUID
AND TECDOC_LOCALE = TDO.TECDOC_LOCALE
AND TECDOC_VERSION > TDO.TECDOC_VERSION
*/
ON (TDO.TECDOC_VERSION < TDO1.TECDOC_VERSION)
AND ((TDO.TECDOC_GUID = TDO1.TECDOC_GUID)
AND (TDO.TECDOC_LOCALE = TDO1.TECDOC_LOCALE))
/* scanCount: 4 */
WHERE (TDO.TECDOC_LOCALE = 'de')
AND ((TDO.TECDOC_GUID IN('GUID-F2F77CE5-D8F5-4286-9A30-8FD500F735F6', 'GUID-41FD28DC-63C0-44D0-B8AE-0FCF7C78CEB0'))
AND (TDO1.ID IS NULL))
/*
total: 11891
TECDOC_OBJECTS.IDX_GUID_LOCALE_VERSION read: 11884 (99%)
TECDOC_OBJECTS.TECDOC_OBJECTS_DATA read: 7 (0%)
*/
Но на моем ноутбуке разработчика после ANALYZE
запрос все еще быстрый. Каким-то образом H2 использует неправильный индекс (так как он может использовать только один индекс для объединения, согласно документации).
У кого-нибудь есть предложения?