Ответ 1
Я тестировал производительность различного синтаксиса для не равного оператора в Oracle. Я попытался устранить все внешние воздействия для теста.
Я использую базу данных 11.2.0.3. Никакие другие сеансы не подключены, и база данных была перезапущена до начала тестов.
Схема была создана с одной таблицей и последовательностью для первичного ключа
CREATE TABLE loadtest.load_test (
id NUMBER NOT NULL,
a VARCHAR2(1) NOT NULL,
n NUMBER(2) NOT NULL,
t TIMESTAMP NOT NULL
);
CREATE SEQUENCE loadtest.load_test_seq
START WITH 0
MINVALUE 0;
Таблица была проиндексирована для повышения производительности запроса.
ALTER TABLE loadtest.load_test
ADD CONSTRAINT pk_load_test
PRIMARY KEY (id)
USING INDEX;
CREATE INDEX loadtest.load_test_i1
ON loadtest.load_test (a, n);
Десять миллионов строк были добавлены в таблицу с использованием последовательности SYSDATE
для временной метки и случайных данных через DBMS_RANDOM (A-Z) и (0-99) для двух других полей.
SELECT COUNT(*) FROM load_test;
COUNT(*)
----------
10000000
1 row selected.
Схема была проанализирована для обеспечения хорошей статистики.
EXEC DBMS_STATS.GATHER_SCHEMA_STATS(ownname => 'LOADTEST', estimate_percent => NULL, cascade => TRUE);
Три простых запроса: -
SELECT a, COUNT(*) FROM load_test WHERE n <> 5 GROUP BY a ORDER BY a;
SELECT a, COUNT(*) FROM load_test WHERE n != 5 GROUP BY a ORDER BY a;
SELECT a, COUNT(*) FROM load_test WHERE n ^= 5 GROUP BY a ORDER BY a;
Это точно то же самое, за исключением синтаксиса оператора не равно (не только < > и! =, но также ^ =)
Сначала каждый запрос запускается без сбора результата, чтобы исключить эффект кэширования.
Следующие тайминги и аутсорсинг были включены для сбора как фактического времени выполнения запроса, так и плана выполнения.
SET TIMING ON
SET AUTOTRACE TRACE
Теперь запросы запускаются поочередно. Первое - это & lt; >
> SELECT a, COUNT(*) FROM load_test WHERE n <> 5 GROUP BY a ORDER BY a;
26 rows selected.
Elapsed: 00:00:02.12
Execution Plan
----------------------------------------------------------
Plan hash value: 2978325580
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 26 | 130 | 6626 (9)| 00:01:20 |
| 1 | SORT GROUP BY | | 26 | 130 | 6626 (9)| 00:01:20 |
|* 2 | INDEX FAST FULL SCAN| LOAD_TEST_I1 | 9898K| 47M| 6132 (2)| 00:01:14 |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("N"<>5)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
22376 consistent gets
22353 physical reads
0 redo size
751 bytes sent via SQL*Net to client
459 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
26 rows processed
Далее!=
> SELECT a, COUNT(*) FROM load_test WHERE n != 5 GROUP BY a ORDER BY a;
26 rows selected.
Elapsed: 00:00:02.13
Execution Plan
----------------------------------------------------------
Plan hash value: 2978325580
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 26 | 130 | 6626 (9)| 00:01:20 |
| 1 | SORT GROUP BY | | 26 | 130 | 6626 (9)| 00:01:20 |
|* 2 | INDEX FAST FULL SCAN| LOAD_TEST_I1 | 9898K| 47M| 6132 (2)| 00:01:14 |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("N"<>5)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
22376 consistent gets
22353 physical reads
0 redo size
751 bytes sent via SQL*Net to client
459 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
26 rows processed
Наконец, ^ =
> SELECT a, COUNT(*) FROM load_test WHERE n ^= 5 GROUP BY a ORDER BY a;
26 rows selected.
Elapsed: 00:00:02.10
Execution Plan
----------------------------------------------------------
Plan hash value: 2978325580
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 26 | 130 | 6626 (9)| 00:01:20 |
| 1 | SORT GROUP BY | | 26 | 130 | 6626 (9)| 00:01:20 |
|* 2 | INDEX FAST FULL SCAN| LOAD_TEST_I1 | 9898K| 47M| 6132 (2)| 00:01:14 |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("N"<>5)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
22376 consistent gets
22353 physical reads
0 redo size
751 bytes sent via SQL*Net to client
459 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
26 rows processed
План выполнения для трех запросов идентичен, а тайминги 2.12, 2.13 и 2.10 секунды.
Следует отметить, что в зависимости от того, какой синтаксис используется в запросе, в плане выполнения всегда отображается < >
Тесты повторялись десять раз для каждого синтаксиса оператора. Это тайминги: -
<>
2.09
2.13
2.12
2.10
2.07
2.09
2.10
2.13
2.13
2.10
!=
2.09
2.10
2.12
2.10
2.15
2.10
2.12
2.10
2.10
2.12
^=
2.09
2.16
2.10
2.09
2.07
2.16
2.12
2.12
2.09
2.07
Пока существует некоторая дисперсия нескольких сотых секунды, это не имеет значения. Результаты для каждого из трех вариантов синтаксиса одинаковы.
Выбор синтаксиса анализируется, оптимизируется и возвращается с одинаковыми усилиями в одно и то же время. Поэтому в этом тесте нет ощутимой выгоды от использования одного над другим.
"Ah BC", вы говорите: "В моих тестах я считаю, что есть реальная разница, и вы не можете доказать это иначе".
Да, я говорю, это совершенно верно. Вы не показывали свои тесты, запросы, данные или результаты. Поэтому мне нечего сказать о ваших результатах. Я показал, что при прочих равных условиях не имеет значения, какой синтаксис вы используете.
"Так почему я вижу, что лучше в моих тестах?"
Хороший вопрос. Есть несколько возможностей: -- Ваше тестирование неверно (вы не устранили внешние факторы - другая рабочая нагрузка, кеширование и т.д. Вы не указали информацию о которые мы можем принять обоснованным решением).
- Ваш запрос - это особый случай (покажите мне запрос, и мы можем обсудить его).
- Ваши данные - это особый случай (возможно, но как - мы тоже этого не видим).
- Существует и другое внешнее влияние.
Я показал через документированный и повторяемый процесс, что нет никакой пользы для использования одного синтаксиса над другим. Я считаю, что < > != И ^ = являются синонимами.
Если вы считаете, что это не так, то
a) показать документированный пример, который я могу попробовать сам
и
b) используйте синтаксис, который вы считаете лучшим. Если я прав, и нет никакой разницы, это не имеет значения. Если вы правы, тогда остынь, у вас есть улучшение для очень небольшой работы.
"Но Берлсон сказал, что это лучше, и я доверяю ему больше, чем ты, Фарул, Льюис, Ките и все остальные бомжи".
Он сказал, что это лучше? Я так не думаю. Он не представил ни одного окончательного примера, теста или результата, а только связался с кем-то, говорящим, что!= Лучше, а затем процитировал некоторые из своих сообщений.
Показывать не говорят.