2017-01-18 2 views
1

Я сражаюсь с случаем глупости/упрямства клиентов здесь. У нас есть приложение для поиска розничного покупателя по различным критериям. Наиболее распространенным видом, который мы видим, является некоторая комбинация (частичная) фамилии и (частичный) почтовый код.индекс oracle для похожих запросов

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

Любое чудо, чтобы преодолеть нашу глупость наших клиентов?

ETA: В этой конкретной собаке есть две таблицы операций: клиенты и адреса. Я - администратор базы данных, участвующий в поддержке этого приложения, а не на стороне разработки. У меня нет возможности изменить код (хотя я могу передать предложения в этом ключе), но у меня есть некоторая свобода в улучшении индексации.

У клиентов есть 22 миллиона строк; адресов - 23 миллиона.

«Глупость» может быть суровым словом, но я не понимаю, почему вы попытаетесь найти клиента по почтовому индексу, например «3%». Я имею в виду, сколько усилий стоит набрать полный почтовый индекс или почтовый индекс?

+0

Когда клиент глуп, каково влияние? Разрывы приложений? Низкая производительность? Что-то другое? – BobC

+1

В зависимости от вашей веры, вы можете молиться или вы можете предположить, что чудес не существует. Кроме того, то, что вы представили до сих пор, не доказывает, что ваш клиент глуп без разумных сомнений; было бы лучше оставить это. Теперь: если у вас есть соответствующие индексы, убедитесь, что статистика обновлена. Кроме того, распределение почтовых кодов может быть искажено; вам может понадобиться использовать гистограммы. – mathguy

+1

Кстати, снова взглянув на ваш заголовок: если у вас есть индекс почтового кода, оптимизатор может использовать его в запросах с такими условиями, как 'like '3%'' - до тех пор, пока подстановочный знак находится в конце. Он не сможет использовать его для такого состояния, как 'like '% 3'', но это не ** ваш случай. Таким образом, проблема не в индексе; проблемой может быть статистика и, возможно, дико неравномерное распределение почтовых кодов. – mathguy

ответ

1

Трудность в том, что

WHERE postal_code LIKE '3%' 
AND last_name LIKE 'MC%' 

обычно может только извлечь выгоду из любого индекса на postal_code или индекс на last_name. Сводный индекс на обоих не помогает (за пределами ведущей колонки).

Рассмотрим это в качестве возможного решения (при условии, ваше имя таблицы RETAIL_RECORDS:

alter table retail_records 
    add postal_code_first_1 VARCHAR2(2) 
     GENERATED ALWAYS AS (substr(postal_code, 1,1)); 

alter table retail_records 
    add last_name_first_1 VARCHAR2(2) 
     GENERATED ALWAYS AS (substr(last_name, 1,1)); 

create index retail_records_n1 
    on retail_records (postal_code_first_1, last_name_first_1, postal_code); 

create index retail_records_n2 
    on retail_records (postal_code_first_1, last_name_first_1, last_name); 

Тогда, в ситуациях, когда postal_code и/или last_name условия даны вам, также включают в себя состояние на соответствующем ...first_1 колонка.

Так,

WHERE postal_code LIKE :p1 
AND last_name LIKE :p2 
AND postal_code_first_1 = SUBSTR(:p1,1,1) 
AND last_name_first_2 = SUBSTR(:p2,1,2) 

Это собирается позволить Oracle в среднем, поиск беспересадочный ugh 1/260th данных. (1/10 для почтовых индексов и 1/26 для первой буквы). Хорошо, есть намного больше имен, начиная с «М», чем с «Z», так что это немного щедро. Но даже для высокочастотной комбинации (скажем, postal_code like '1%' and last_name like 'M%') ей все равно не нужно просматривать более 1% строк.

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

+0

Я явно не задал вопрос достаточно ясно. Есть две таблицы, клиенты и адреса. Проблема в том, что поиск по почтовому индексу, например «3%», вернет 3 миллиона строк из адресов, которые необходимо объединить с некоторыми подмножествами клиентов ... все подчиняются прихоти конечного пользователя. – stephan

+0

Ugh. Это меняет все. Я бы посмотрел на денормализацию некоторых данных в одну из таблиц. В противном случае материализованное представление «FAST REFRESH ON COMMIT» о соединении между таблицами было бы опасным, но правдоподобным. Действительно хорошая статья об этом здесь: https://orastory.wordpress.com/2014/11/27/the-mess-that-is-fast-refresh-join-only-materialized-views/. –