Проблемы производительности DBMS_CRYPTO - PullRequest
2 голосов
/ 25 января 2012

Я использую DBMS_CRYPTO для защиты информации в случае взлома БД.Ключ не сохраняется в базе данных и вместо этого предоставляется приложением при каждом доступе.

A select decrypt(name), seq order by seq запрос занимает (почти точно) в 15 раз больше времени, чем

select decrypt(name), seq

или

select name, seq order by seq

Что наводит меня на мысль, что функция дешифрования нарушает индекс первичного ключа seq.Почему это сломалось?

Я попытался добавить ключевое слово DETERMINISTIC к типу вывода функции, но оно сокращает время примерно в 10 раз по сравнению с более быстрыми запросами.Я не понимаю, почему это должно занять больше времени, чем select decrypt(name), seq. Редактировать : ключевое слово DETERMINISTIC также ускорило простой запрос на дешифрование, как и следовало ожидать.

Мои ожидания неверны или это что-то еще?Я в порядке с задержкой в ​​300 мс, учитывая ограничения безопасности, которые мне дали, но 3000 мс заметны, и я хотел бы сделать это быстрее.

Я использую инструмент БД под названием SmartSQL, который даетотображение прошедшего времени (я предполагаю время между отправкой запроса и получением последнего бита результата).

Существует один индекс, первичный ключ, на seq.Я полагаю, что размещение индекса на зашифрованных значениях не поможет.

Планы выполнения:

выбрать расшифровку (имя), seq

------------------------------------------------------------------------------------
| Id  | Operation         | Name           | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |                |  8810 |  1453K|    98   (3)| 00:00:02 |
|   1 |  TABLE ACCESS FULL| CSTN_MEMB_INFO |  8810 |  1453K|    98   (3)| 00:00:02 |
------------------------------------------------------------------------------------

выбрать имя, последующий порядок по seq desc

---------------------------------------------------------------------------------------------
| Id  | Operation          | Name           | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |                |  8810 |  1453K|       |   428   (1)| 00:00:06 |
|   1 |  SORT ORDER BY     |                |  8810 |  1453K|  3448K|   428   (1)| 00:00:06 |
|   2 |   TABLE ACCESS FULL| CSTN_MEMB_INFO |  8810 |  1453K|       |    98   (3)| 00:00:02 |
---------------------------------------------------------------------------------------------

выбрать расшифровку(имя), порядок следования по seq desc

---------------------------------------------------------------------------------------------
| Id  | Operation          | Name           | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |                |  8810 |  1453K|       |   428   (1)| 00:00:06 |
|   1 |  SORT ORDER BY     |                |  8810 |  1453K|  3448K|   428   (1)| 00:00:06 |
|   2 |   TABLE ACCESS FULL| CSTN_MEMB_INFO |  8810 |  1453K|       |    98   (3)| 00:00:02 |
---------------------------------------------------------------------------------------------

Мои полные запросы выглядят так:

select 
    seq, gender, wdate, address, 
    my_crypto_pkg.decrypt(tel, 'my_secret_key'), 
    my_crypto_pkg.decrypt(name, 'my_secret_key') 
from cstn_memb_info
--  where my_crypto_pkg.decrypt(name, 'my_secret_key') like ?
order by
    seq desc

1 Ответ

3 голосов
/ 25 января 2012

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

Если вы исключите вызов decrypt, то вы просто сканируете таблицу, и вам не нужно вызывать отдельную функцию для дешифрования данных (что гораздо дороже, чем просто чтение). Если вы исключите ORDER BY, Oracle просто расшифрует первые N строк перед возвратом данных и даже не завершит сканирование таблицы. Если вы расшифровываете данные и упорядочиваете результаты, то вам придется расшифровать все данные, прежде чем произойдет сортировка, и результаты могут начать возвращаться. Время выборки последней строки также будет самым длинным для запроса, который выполняет как decrypt, так и ORDER BY, но разница будет гораздо менее существенной. Как только вы добавите предикат к расшифрованному значению, все запросы должны работать как минимум медленнее, чем самый медленный из трех запросов, что намного больше соответствует запросу, который вы хотите выполнить в конце.

Реально, так как вы намерены иметь предикат для расшифрованного значения и поскольку ключ шифрования передается во время выполнения, вам придется выполнить полное сканирование таблицы, расшифровывая каждую строку, перед тем как заказать Результаты. Это будет довольно медленно по мере увеличения объемов данных. Это также обычно не совместимо с тем, что вы описываете, когда говорите о «разбивке на страницы». Поскольку вам нужно расшифровывать каждую строку каждый раз, когда вы запускаете этот запрос, вы не хотите писать запрос, который возвращает первые 10 строк, затем выдает другой запрос для получения строк 11-20 и так далее. Каждый раз, когда вы извлекаете страницу данных, вам нужно будет повторно расшифровывать каждую строку в таблице.

Если вы использовали 11g, использование функции кэша результатов потенциально могло бы позволить вам выполнять отдельные запросы для извлечения отдельных страниц данных достаточно эффективным способом. Но это не доступно в 10 г.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...