Существует хорошая реализация Эффективный Java hashcode()
и equals()
логика в Apache Commons Lang . Контроль HashCodeBuilder и EqualsBuilder.
Проблема в том, что в приведенном выше коде не используются дженерики .
Будет работать следующее:
Vector<Integer> moves = new Vector<Integer>();
move.add(new Integer(x));
Имя типа внутри <>
(в случае Vector
параметр типа E
для удерживаемого элемента) сообщает компилятору, какой тип объекта следует ожидать.
Если кто-то пытается добавить объект указанного типа, например, в этом случае, пытается добавить String
к и Vector
, произойдет ошибка времени компиляции, указывающая, что добавляется тип объекта, который не является ожидаемым.
При этом следует стараться не использовать класс Vector
. Для большего количества целей В многопользовательской среде мой COUNT (*)
может отличаться от вашего COUNT (*)
. Было бы непрактично иметь разные счетчики для каждого сеанса, чтобы вам приходилось буквально подсчитывать строки. В любом случае в большинстве случаев у вас будет предложение WHERE или JOIN в вашем запросе, поэтому ваш гипотетический счетчик будет иметь небольшую практическую ценность.
Однако есть способы ускорить процесс: если у вас есть INDEX в столбце NOT NULL Oracle будет считать строки индекса вместо таблицы. В правильной реляционной модели все таблицы имеют первичный ключ, поэтому COUNT (*)
будет использовать индекс первичного ключа.
Bitmap index имеет записи для NULL строк, поэтому COUNT (*) будет использовать индекс растрового изображения, если он доступен.
Было бы непрактично иметь разные счетчики для каждого сеанса, чтобы вам приходилось буквально подсчитывать строки. В любом случае в большинстве случаев у вас будет предложение WHERE или JOIN в вашем запросе, поэтому ваш гипотетический счетчик будет иметь небольшую практическую ценность. Однако есть способы ускорить процесс: если у вас есть INDEX в столбце NOT NULL Oracle будет считать строки индекса вместо таблицы. В правильной реляционной модели все таблицы имеют первичный ключ, поэтому COUNT (*)
будет использовать индекс первичного ключа.
Bitmap index имеет записи для NULL строк, поэтому COUNT (*) будет использовать индекс растрового изображения, если он доступен.
Было бы непрактично иметь разные счетчики для каждого сеанса, чтобы вам приходилось буквально подсчитывать строки. В любом случае в большинстве случаев у вас будет предложение WHERE или JOIN в вашем запросе, поэтому ваш гипотетический счетчик будет иметь небольшую практическую ценность. Однако есть способы ускорить процесс: если у вас есть INDEX в столбце NOT NULL Oracle будет считать строки индекса вместо таблицы. В правильной реляционной модели все таблицы имеют первичный ключ, поэтому COUNT (*)
будет использовать индекс первичного ключа.
Bitmap index имеет записи для NULL строк, поэтому COUNT (*) будет использовать индекс растрового изображения, если он доступен.
В любом случае в большинстве случаев у вас будет предложение WHERE или JOIN в вашем запросе, поэтому ваш гипотетический счетчик будет иметь небольшую практическую ценность. Однако есть способы ускорить процесс: если у вас есть INDEX в столбце NOT NULL Oracle будет считать строки индекса вместо таблицы. В правильной реляционной модели все таблицы имеют первичный ключ, поэтому COUNT (*)
будет использовать индекс первичного ключа.
Bitmap index имеет записи для NULL строк, поэтому COUNT (*) будет использовать индекс растрового изображения, если он доступен.
В любом случае в большинстве случаев у вас будет предложение WHERE или JOIN в вашем запросе, поэтому ваш гипотетический счетчик будет иметь небольшую практическую ценность. Однако есть способы ускорить процесс: если у вас есть INDEX в столбце NOT NULL Oracle будет считать строки индекса вместо таблицы. В правильной реляционной модели все таблицы имеют первичный ключ, поэтому COUNT (*)
будет использовать индекс первичного ключа.
Bitmap index имеет записи для NULL строк, поэтому COUNT (*) будет использовать индекс растрового изображения, если он доступен.
Если вам нужна только приблизительная оценка, вы можете экстраполировать из образца:
SELECT COUNT (*) * 100 FROM sometable SAMPLE (1);
Для большей скорости (но меньшая точность) вы можете уменьшить размер выборки:
SELECT COUNT (*) * 1000 FROM sometable SAMPLE (0.1);
Для еще большей скорости (но еще худшей точности) вы можете использовать блочную выборку:
SELECT COUNT (*) * 100 FROM sometable SAMPLE BLOCK (1);
Если таблица имеет индекс в столбце NOT NULL, то COUNT (*) будет использовать его. В противном случае выполняется полное сканирование таблицы. Обратите внимание, что индекс не обязательно должен быть УНИКАЛЬНЫМ, он просто должен быть НЕ ПУСТОЙ.
Вот таблица ...
SQL> desc big23
Name Null? Type
----------------------------------------- -------- ---------------------------
PK_COL NOT NULL NUMBER
COL_1 VARCHAR2(30)
COL_2 VARCHAR2(30)
COL_3 NUMBER
COL_4 DATE
COL_5 NUMBER
NAME VARCHAR2(10)
SQL>
Сначала мы проведем подсчет без индексов ....
SQL> explain plan for
2 select count(*) from big23
3 /
Explained.
SQL> select * from table(dbms_xplan.display)
2 /
select * from table)dbms_xplan.display)
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------
Plan hash value: 983596667
--------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
--------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 1618 (1)| 00:00:20 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | TABLE ACCESS FULL| BIG23 | 472K| 1618 (1)| 00:00:20 |
--------------------------------------------------------------------
Note
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------
- dynamic sampling used for this statement
13 rows selected.
SQL>
Нет мы создаем индекс для столбца, который может содержать записи NULL ...
SQL> create index i23 on big23(col_5)
2 /
Index created.
SQL> delete from plan_table
2 /
3 rows deleted.
SQL> explain plan for
2 select count(*) from big23
3 /
Explained.
SQL> select * from table(dbms_xplan.display)
2 /
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------
Plan hash value: 983596667
--------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
--------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 1618 (1)| 00:00:20 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | TABLE ACCESS FULL| BIG23 | 472K| 1618 (1)| 00:00:20 |
--------------------------------------------------------------------
Note
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------
- dynamic sampling used for this statement
13 rows selected.
SQL>
Наконец, давайте создадим индекс для столбца NOT NULL ....
SQL> drop index i23
2 /
Index dropped.
SQL> create index i23 on big23(pk_col)
2 /
Index created.
SQL> delete from plan_table
2 /
3 rows deleted.
SQL> explain plan for
2 select count(*) from big23
3 /
Explained.
SQL> select * from table(dbms_xplan.display)
2 /
PLAN_TABLE_OUTPUT
---------------------------------------------------------------------
Plan hash value: 1352920814
----------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 326 (1)| 00:00:04 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | INDEX FAST FULL SCAN| I23 | 472K| 326 (1)| 00:00:04 |
----------------------------------------------------------------------
Note
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------
- dynamic sampling used for this statement
13 rows selected.
SQL>
Вариант 1. Иметь индекс для ненулевого столбца, который можно использовать для сканирования. Или создайте функциональный индекс как:
create index idx on t(0);
, затем его можно просканировать, чтобы получить счет.
Вариант 2: Если у вас включен мониторинг, проверьте представление мониторинга USER_TAB_MODIFICATIONS и добавьте / вычтите соответствующие значения в таблицу. статистика.
Вариант 3: Для быстрой оценки больших таблиц вызовите предложение SAMPLE ... например ...
SELECT 1000*COUNT(*) FROM sometable SAMPLE(0.1);
Вариант 4: Используйте материализованное представление для поддержания счетчика (*). Но мощное лекарство.
ммм ...
Вы можете создать материализованное представление с быстрым обновлением для хранения счетчика.
Пример:
create table sometable (
id number(10) not null primary key
, name varchar2(100) not null);
create materialized view log on sometable with rowid including new values;
create materialized view sometable_count
refresh on commit
as
select count(*) count
from sometable;
insert into sometable values (1,'Raymond');
insert into sometable values (2,'Hans');
commit;
select count from sometable_count;
Это немного замедлит мутации в таблице sometable, но подсчет станет намного быстрее.
Самый быстрый способ подсчета таблицы - это именно то, что вы сделали. Нет никаких уловок, о которых Oracle еще не знает.
Есть кое-что, о чем вы нам не сказали. А именно, почему вы думаете, что это должно быть быстрее?
Например:
Признаюсь, я бы не стал Не радуйтесь 41 секунде, но почему вы думаете, что она должна быть быстрее? Если вы скажете нам, что таблица имеет 18 миллиардов строк и работает на ноутбуке, который вы купили на гаражной распродаже в 2001 году, 41 секунда, вероятно, не так уж и далеко от «хорошего, насколько она будет», если вы не приобретете лучшее оборудование. Однако, если вы скажете, что используете Oracle 9 и хорошо провели статистику прошлым летом, вы, вероятно, получите другие предложения.