Оптимизация запроса SELECT в Oracle 10 Dense Уникальный индекс - PullRequest
1 голос
/ 29 мая 2009

У меня есть таблица в Oracle 10 со следующей структурой

Create Table Bookmarks(  
    BOOKMARKID NUMBER(10,0) NOT NULL PRIMARY KEY,
    URL VARCHAR2(4000 CHAR) NOT NULL UNIQUE
)

URL имеет уникальное ограничение, таким образом, уникальный индекс. В этой таблице около 1 миллиона записей. Я должен часто проверять, существует ли закладка в таблице. Я выдаю следующий запрос

Select bookmarkid from Bookmarks where URL='<some url>'

Проблема в том, что с ростом количества записей производительность снижается. Теперь требуется значительно больше времени, чтобы вернуть идентификатор закладки, особенно если URL-адрес запроса длинный. В плане объяснения запрос использует уникальный индекс для столбца URL. Есть предложения по улучшению времени отклика?

Ответы [ 4 ]

3 голосов
/ 29 мая 2009

Сделать индекс, который также включает в себя столбец bookmarkid. Как это:

create IX on bookmarks (url, bookmarkid);
3 голосов
/ 29 мая 2009

Для этого вы обычно используете хеш-индекс. В mssql я бы создал постоянный вычисляемый столбец, который был бы похож на CRC (url). Затем, когда вы хотите проверить наличие, вы ищете WHERE crc ('some url') = PersistedCrcColumn AND URL = 'some url'

Вы должны включить исходную проверку в проверку crc, поскольку вы можете время от времени получать коллизии CRC.

РЕДАКТИРОВАТЬ - изменение моего описания выше с «поиска хеша» на «индекс хеша», чтобы избежать путаницы. Некоторые базы данных имеют хеш-индексы в качестве индекса первого класса, я не верю, что у oracle есть (и я знаю, что mssql нет). Если он не поддерживается по своей природе, описанный выше подход заключается в том, как реализовать его вручную.

2 голосов
/ 30 мая 2009

Убедитесь, что план выполнения использует УНИКАЛЬНОЕ сканирование индекса, а не полное / быстрое сканирование полного диапазона. Вероятно, у вас есть много URL-адресов, начинающихся с http://www. (и, возможно, также намного больше ведущих значений), что не идеально. Если вы можете, перейдите к созданию неуникального индекса на основе функции для ORA_HASH (url) и добавьте его к запросам. Это даст намного меньшее индексированное значение с гораздо лучшим разбросом значений. Если изменение запросов невозможно, попробуйте заново создать индекс с помощью REVERSE .

Это не поможет с размером индексированного значения, но может распространить его лучше.

2 голосов
/ 29 мая 2009

Рассчитайте MD4 индекс для вашего URL и назначьте его в триггере:

:new.HASH := DBMS_CRYPTO.hash(UTL_RAW.cast_to_raw(:new.url), 1)

Создайте индекс для этого столбца и выполните поиск по хеш-значению.

Не забудьте GRANT EXECUTE на DBMS_CRYPTO пользователю, владеющему триггером.

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

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