Оптимизировать несколько запросов ИЛИ - PullRequest
2 голосов
/ 20 января 2011

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

Вот что я думаю

Макет БД

rec_id (pk), user_id,
name, phone, address_1, address_2, zip, 
company, co_phone, co_address_1, co_address_2, co_zip, 
billing, bi_phone, bi_address_1, bi_address_2, bi_zip

Запрос

SELECT rec_id 
FROM tbl_name
WHERE user_id = '123456789'
OR '1112223333' IN (phone, co_phone, bi_phone)
OR 'John Doe' IN (name, business, billing)
OR '12345' IN (zip, co_zip, bi_zip)
OR '123 main street' IN (address_1, co_address_1, bi_address_1)
OR 'po box 123' IN (address_2, co_address_2, bi_address_2)

Если какие-либо данные совпадают (и да, это будут ложные срабатывания), мне нужен старый rec_id.

Хотели бы узнать, есть ли лучший способ сделать это?

Спасибо

1 Ответ

2 голосов
/ 20 января 2011

Для правильной работы этого запроса вам потребуются отдельные индексы для каждого из тестируемых столбцов. Объединенный индекс по всем столбцам не поможет вообще для условий ИЛИ (хотя, если бы у вас были AND, это помогло бы.)

Однако я бы предположил, что ваш запрос приведет к полному сканированию таблицы независимо от того, какие индексы вы добавите. Возможно, вы захотите попробовать использовать UNION вместо OR, чтобы увидеть, имеет ли это значение:

SELECT rec_id FROM tbl_name WHERE tax_id = '123456789'
UNION
SELECT rec_id FROM tbl_name WHERE phone = '1112223333'
UNION
SELECT rec_id FROM tbl_name WHERE co_phone = '1112223333'
UNION
SELECT rec_id FROM tbl_name WHERE bi_phone = '1112223333'
UNION
SELECT rec_id FROM tbl_name WHERE name = 'John Doe'
UNION
SELECT rec_id FROM tbl_name WHERE business = 'John Doe'
UNION
SELECT rec_id FROM tbl_name WHERE billing = 'John Doe'
UNION
-- etc...

Идея переписать его таким образом заключается в том, что теперь каждый подзапрос сможет использовать индекс (если, конечно, вы добавили необходимые индексы).

...