Есть ли способ в спящем режиме получить быстрое неблокирующее количество строк?

Следующий запрос, сгенерированный спящим режимом, занимает более 13 секунд и блокирует таблицу:

SELECT COUNT(auditentit0_.audit_id) AS col_0_0_ FROM Audit auditentit0_ WHERE 1=1; 

Растущая таблица базы данных сервера Microsoft SQL содержит более 90 миллионов строк.

Для сервера Microsoft SQL я нашел точный способ очень быстрого получения той же информации с помощью метаданных.

Однако я бы предпочел не писать собственный код для Microsoft sql server и oracle (следующей базы данных), если в hibernate есть способ получить эту информацию.

Вот пример запроса метаданных для Microsoft sql server, который является точным и почти мгновенным:

SELECT SUM (row_count) FROM sys.dm_db_partition_stats WHERE object_id=OBJECT_ID('huge_audit_table') AND (index_id=0 or index_id=1);

Есть ли способ заставить спящий режим выдавать аналогичный запрос для количества строк таблицы?


Один опубликованный ответ показал, что представление может быть полезно. Я изучаю этот пост, чтобы узнать, может ли он решить проблему:

https://vladmihalcea.com/map-jpa-entity-to-view-or-sql-query-with-hibernate/

1) что именно вы подразумеваете под «блокирует стол»? Я никогда раньше не видел, чтобы запрос SELECT что-либо блокировал. 2) полное сканирование таблицы выглядит неправильно, я ожидал бы быстрого сканирования индекса по столбцу PK. 3) почему ГДЕ 1 = 1? условие не обязательно. 4) это Oracle или MS SQL? 5) метаданные - это скорее оценка, чем правильное значение

Kousalik 31.07.2018 01:05

Зачем тебе это? результат статистики. никогда не будет точным. Но практически никакое количество строк таблицы не может быть точным - по крайней мере, в Oracle. Чтение всегда неблокирующее, поэтому количество строк может измениться во время чтения.

ibre5041 31.07.2018 01:06

@ ibre5041 он блокирует. Взгляните здесь для получения дополнительной информации: sqlperformance.com/2014/10/t-sql-queries/…

D-Klotz 31.07.2018 01:11

@Kousalik Да, блокирует. Взгляните сюда: sqlperformance.com/2014/10/t-sql-queries/…. Приведенный мной пример запроса метаданных является точным. Напомним, что мы говорим о 90+ миллионах строк, это занимает более 14 секунд при использовании высокопроизводительной системы, и в течение этого времени таблица заблокирована. Ничего другого выполнить нельзя. Возможно, это проблема, связанная с сервером sql. Я хотел бы найти решение для гибернации.

D-Klotz 31.07.2018 01:11

@ D-Klotz меняет теги с Oracle11g на MSSQL

Kousalik 31.07.2018 01:17

@Kousalik - это не sql-server тег Microsoft? Я хочу сохранить тег oracle, потому что это наша следующая цель. Однако, ближе к делу, я хотел бы найти решение для гибернации, которое будет работать как с сервером sql, так и с Oracle, если оно существует. Боюсь, что это не так.

D-Klotz 31.07.2018 01:19

счетчик выбора в Oracle не блокируется, а словари метаданных отличаются. Я не думаю, что есть такое решение. gl

Kousalik 31.07.2018 01:23

@Kousalik спасибо за эту информацию. +1 вам.

D-Klotz 31.07.2018 01:24

не вдаваясь в детали реализации, я бы рассмотрел возможность создания собственного представления и скрытия различий РСУБД за определением представления. Затем вы можете сопоставить представление с простым объектом Hibernate. Имеет ли это смысл? Также может быть хранимая процедура.

Kousalik 31.07.2018 01:29

@Kousalik Раньше я находил ссылки на просмотры. Спасибо. Я покопаюсь и посмотрю, работает ли.

D-Klotz 31.07.2018 01:37
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
10
520
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

В спящем режиме вы должны использовать проекции, как в предоставленной вами ссылке, чтобы гарантировать, что он работает с несколькими базами данных:

protected Long countByCriteria(DetachedCriteria criteria) {
   Criteria crit = criteria.getExecutableCriteria(getSession());
   crit.setProjection(Projections.rowCount());
   return (Long)crit.uniqueResult();
}

Какой движок вы используете в MySQL? У меня никогда не было проблем с блокировкой количества строк в MySql или Oracle. Возможно, вам поможет следующая ссылка: Любой способ выбрать, не вызывая блокировки в MySQL?

Кроме того, после некоторого быстрого чтения я вижу, что Sql Server действительно блокируется по счетчику.

Возможно, вы могли бы использовать хранимую процедуру или какой-либо другой механизм, чтобы передать проблему в dbms.


Редактировать:

Проекции в Hibernate используются для выбора столбцов для выборки, столбцов для группировки элементов и использования встроенных агрегатных функций (sum, count, avg, max, min, countDistinct).

Это поможет вам сохранить привязку к базе данных вашего приложения. Помните, что спящий режим поддерживает около 30 баз данных.

В вашем случае у вас есть конкретная проблема с mssql, поскольку счетчик блокирует точность определения приоритетов таблицы. А использование системных представлений происходит очень быстро, поскольку вы получаете приблизительную оценку, но это нестандартно.

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

Я не знаком с прогнозами, кроме быстрого гугла. Что вышеперечисленное делает для вас? Напомним, что проблема заключается в сервере microsoft sql при выполнении подсчета выбора (). Он блокирует таблицу во время сканирования (я предполагаю, индекса). Как вышеприведенная проекция обходит это? Жаль, что в спящем режиме нет чего-то особенного для count () и сервере ms sql, чтобы избежать этого.

D-Klotz 31.07.2018 03:33

Спасибо за информацию. NOLOCK поможет, но запрос по-прежнему занимает более 13 секунд, что недопустимо. Я изучу "представление" и посмотрю, может ли оно скрыть код, специфичный для Microsoft sql server. Если сработает, я поставлю +1 и отмечу как ответ. Спасибо.

D-Klotz 31.07.2018 15:01

Преимущество представления в том, что вы можете использовать другие методы, специфичные для dbms, для получения оценок количества строк. В mysql вы можете получить оценку из INFORMATION_SCHEMA или TABLE STATUS, но вам следует изучить допустимую погрешность.

Sergio Daniel Coronel Malvarez 31.07.2018 15:15

Чтобы решить эту конкретную проблему, мы отступили и изменили работу пользовательского интерфейса. Благодаря совместным усилиям разработчиков UIX и пользовательского интерфейса мы договорились, что нефильтрованные запросы НЕ будут запрашивать общее количество. При начальной загрузке экрана будет отображаться только страница, полная данных. Страница 1 из 60 000 элементов управления не существует. Только когда пользователь вводит определенные критерии, в игру вступает общий счет. Эти запросы должны быть очень быстрыми. Теперь ... пользователь все еще может настроить запрос, который будет таким же серьезным, как и исходная проблема. Это должно быть исключением из нормы.

D-Klotz 02.08.2018 23:13

Я помню, что однажды у нас была похожая проблема, и мы то, что мы сделали, отображали что-то вроде «Page 1 - 2 - 3 - 4 - ... - 10 из многих». Не идеально, но позволяет избежать проблемы.

Sergio Daniel Coronel Malvarez 03.08.2018 13:32
Ответ принят как подходящий

Чтобы решить эту конкретную проблему, мы отступили и изменили работу пользовательского интерфейса. Благодаря совместным усилиям разработчиков UIX и пользовательского интерфейса мы договорились, что нефильтрованные запросы НЕ будут запрашивать общее количество. При начальной загрузке экрана будет отображаться только страница, полная данных. Страница 1 из 60 000 элементов управления не существует. Только когда пользователь вводит определенные критерии, в игру вступает общий счет. Эти запросы должны быть очень быстрыми. Теперь ... пользователь все еще может настроить запрос, который будет таким же серьезным, как и исходная проблема. Это должно быть исключением из нормы.

Так что на ОП действительно нет однозначного ответа. Если вы столкнулись с проблемой такого типа, если у вас есть контроль над пользовательским интерфейсом и API, то пришло время переосмыслить решение. Подумайте о том, как Google обрабатывает разбиение на страницы с точки зрения пользовательского интерфейса. Дни показа "страницы 1 из (XX)" ушли в прошлое ИМХО.

Другие вопросы по теме