Самый быстрый способ проверить, есть ли записи в таблице базы данных?

У меня есть огромная таблица для работы. Я хочу проверить, есть ли какие-то записи, parent_id которых равно моему передаваемому значению. в настоящее время я реализую это, используя "select count (*) из mytable, где parent_id =: id"; если результат > 0, означает, что они существуют.

Потому что это очень огромная таблица, и мне все равно, сколько именно записей существует, я просто хочу знать, существует ли она, поэтому я считаю, что count (*) немного неэффективен.

Как реализовать это требование самым быстрым способом? Я использую Oracle 10.

#

В соответствии с hibernate Советы и подсказки https://www.hibernate.org/118.html#A2

Предлагается написать вот так:

Целое число count = (целое число) session.createQuery( "select count (*) from...." ). uniqueResult();

Я не знаю, что это за волшебство uniqueResult() здесь? почему он делает это быстро?

Сравнить с "выберите 1 из mytable, где parent_id = passId и rowrum < 2", что более эффективно?

Ответ 1

Запрос EXISTS - это тот, который нужно выполнить, если вас не интересует количество записей:

select 'Y' from dual where exists (select 1 from mytable where parent_id = :id)

Это вернет "Y", если запись существует и ничего не происходит.

[С точки зрения вашего вопроса в Hibernate "uniqueResult" - все это возвращает один объект, когда возвращается только один объект - вместо набора, содержащего 1 объект. Если возвращено несколько результатов, метод выдает исключение.]

Ответ 2

select count (*) должен быть молниено быстрым, если у вас есть индекс, а если нет, то разрешить остановке базы данных после первого совпадения не поможет.

Но так как вы спросили:

boolean exists = session.createQuery("select parent_id from Entity where parent_id=?")
                        .setParameter(...)
                        .setMaxResults(1)
                        .uniqueResult() 
                 != null;

(Некоторые ожидаемые синтаксические ошибки, так как у меня нет спящего режима для тестирования на этом компьютере)

Для Oracle maxResults транслируется в rownum с помощью спящего режима.

Что касается того, что делает uniqueResult(), прочитайте его JavaDoc! Использование uniqueResult вместо списка() не влияет на производительность; если я правильно помню, реализация делегатов uniqueResult для list().

Ответ 3

Нет реальной разницы между:

select 'y' 
  from dual 
 where exists (select 1 
                 from child_table 
                where parent_key = :somevalue)

и

select 'y' 
  from mytable 
 where parent_key = :somevalue 
   and rownum = 1;

... по крайней мере, в Oracle10gR2 и выше. Oracle достаточно умна в этом выпуске, чтобы выполнить операцию FAST DUAL, где она обнуляет любую реальную активность против нее. Второй запрос будет проще переносить, если это когда-либо будет рассмотрено.

Реальным отличием производительности является то, проиндексирован ли столбец parent_key. Если это не так, вы должны запустить что-то вроде:

select 'y' 
  from dual 
 where exists (select 1 
                 from parent_able 
                where parent_key = :somevalue)

Ответ 4

Прежде всего, вам нужен индекс на mytable.parent_id.

Это должно сделать ваш запрос достаточно быстрым даже для больших таблиц (если не существует также много строк с одним и тем же parent_id).

Если нет, вы можете написать

select 1 from mytable where parent_id = :id and rownum < 2

который возвратит одну строку, содержащую 1, или вообще не строку. Нет необходимости подсчитывать строки, просто найти их и затем выйти. Но это Oracle-специфический SQL (из-за rownum), и вы не должны этого делать.

Ответ 5

Для DB2 есть что-то вроде select * from mytable where parent_id = ? fetch first 1 row only. Я предполагаю, что существует нечто подобное для оракула. ​​

Ответ 6

Этот запрос вернет 1, если какая-либо запись существует, а 0 в противном случае:

SELECT COUNT(1) FROM (SELECT 1 FROM mytable WHERE ROWNUM < 2);

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