Хотя я хорошо разбираюсь в разных областях технической вселенной, я новичок в SQL. Я много раз искал и нашел много похожих вопросов, к сожалению, я не смог понять, что я видел, связав это с моим запросом. Так что будьте добры...
Наше новое программное обеспечение в нашем офисе позволяет создавать новые запросы в нашей базе данных. Я создал поиск, который заставит пользователя ввести номер телефона, и запрос будет искать все учетные записи в нашей системе для этого номера телефона и отображать учетные записи, у которых был этот номер телефона. В нашей системе насчитывается около 179 000 учетных записей, и запрос проверяет номер телефона, указанный в подсказке, в 19 разных полях в 7 разных таблицах.
Поиск работает, но занимает около 33 секунд, который сегодня и днем кажется слишком длинным, особенно для человека, который звонил, за счет которого мы ищем. Но может быть, это так хорошо, как это получится? Я понимаю, что просматриваю много информации. Я также был бы открыт для ограничения результатов по счетам за последние 7 лет, но когда я добавил этот классификатор, он показал только результаты за последние 7 лет, но он не ускорил поиск вообще, поэтому я принял это обратно.
Есть ли способ ускорить этот запрос? Наш простой поиск по телефону, который ищет только одно поле, почти мгновен, и, хотя я этого не ожидаю, мне бы хотелось как можно больше сократить время запроса.
Вот код:
SELECT
'[!Enter Phone Number|String|0]' AS 'Phone',
[email protected] AS 'AccountNumber',
[email protected] AS 'Collector',
[email protected] || ' ' || [email protected] AS 'MakerName',
[email protected] || ' ' || [email protected] AS 'Co-MakerName',
[email protected] AS 'City',
[email protected] AS 'StateAndZip',
[email protected] AS 'DebtorNumber'
FROM COLLDEBT@
LEFT JOIN COLLACCT@ ON [email protected] = [email protected]
LEFT JOIN U_CELLPHN@ ON [email protected] = [email protected]
LEFT JOIN COLLDEBT1@ ON [email protected] = [email protected]
LEFT JOIN U_SPOUSEINFO@ ON [email protected] = [email protected]
LEFT JOIN U_ASTSCRN@ ON [email protected] = [email protected]
LEFT JOIN U_ASTSCRNB@ ON [email protected] = [email protected]
LEFT JOIN AUXDEBTOR@ ON [email protected] = [email protected]
WHERE
[email protected] = Phone
OR [email protected] = Phone
OR [email protected] = Phone
OR [email protected] = Phone
OR [email protected] = Phone
OR [email protected] = Phone
OR [email protected] = Phone
OR [email protected] = Phone
OR [email protected] = Phone
OR [email protected] = Phone
OR [email protected] = Phone
OR [email protected] = Phone
OR [email protected] = Phone
OR [email protected] = Phone
OR [email protected] = Phone
OR [email protected] = Phone
OR [email protected] = Phone
OR [email protected] = Phone
OR [email protected] = Phone
OR [email protected] = Phone
GROUP BY
MakerName
ORDER BY
MakerName
Заранее спасибо!
@otisbartleh, просто чтобы выделить основную структуру подхода, который я опишу в своем комментарии. Я не набрал весь запрос, поэтому я использовал эллипсы, чтобы отразить, где вы будете заполнять.
В основном то, что вы делаете, сначала получает список номеров учетных записей из всех таблиц, соответствующих критериям телефона, а затем, когда у вас есть список совпадающих (и дедуплицированных) номеров учетных записей (которые, как я полагаю, должны быть минимальными), вы в основном просто запрашиваете таблицы для подробностей этих учетных записей (которые должны быть быстрыми).
Если вы выполняете этот запрос несколько раз в день, чтобы найти разные номера телефонов, вам может понадобиться создать таблицу, которая индексирует все номера телефонов в базе данных и сопоставляет их с номерами счетов (что может занять немного времени), а затем легко найти учетные записи, соответствующие любому индивидуальному номеру телефона, потому что у вас уже есть таблица с перекрестной ссылкой.
WITH u_astscrn_matches AS
(
SELECT
masterlink AS master_debtor_id
FROM
U_ASTSCRN@
WHERE
@phone IN (phone0, phone1, phone2, ...)
)
,u_astscrn_b_matches AS
(
SELECT
masterlink AS master_debtor_id
FROM
U_ASTSCRNB@
WHERE
@phone IN (phone10, phone11, phone12, ...)
)
...
,all_matches AS
(
SELECT master_debtor_id FROM u_astscrn_matches
UNION
SELECT master_debtor_id FROM u_astscrn_b_matches
UNION
...
)
SELECT
...
FROM
all_matches AS am
LEFT JOIN
COLLDEBT@ AS cd
ON (cd.recnum = am.master_debtor_id)
LEFT JOIN
... --join onto other tables to get all the debtor details
Msgstr "Не массировать массив по столбцам".
Перестройте схему. У вас есть таблица в основном для телефонных номеров. Вероятно, у него может быть связь 1: много людей с телефонами. (Или вам может понадобиться много: много.)
При этом это простой JOIN
и один тест для номера телефона.
И он избавляется от всех 15 столбцов для телефонных номеров. И он более грациозно работает с людьми с менее чем 15 телефонами. И это позволяет человеку иметь более 15.
Самое прямое решение - использовать UNION, например:
(Примечание. Запрос на самом деле менее сложный, чем кажется, я оставил в оригинальных экземплярах каждый элемент UNION для ясности.)
SELECT
'[!Enter Phone Number|String|0]' AS 'Phone',
[email protected] AS 'AccountNumber',
[email protected] AS 'Collector',
[email protected] || ' ' || [email protected] AS 'MakerName',
[email protected] || ' ' || [email protected] AS 'Co-MakerName',
[email protected] AS 'City',
[email protected] AS 'StateAndZip',
[email protected] AS 'DebtorNumber'
FROM COLLDEBT@
LEFT JOIN COLLACCT@ ON [email protected] = [email protected]
WHERE
[email protected] = Phone
OR [email protected] IN (
-- LEFT JOIN U_CELLPHN@ ON [email protected] = [email protected]
SELECT MASTERLINK FROM U_CELLPHN@ WHERE CELLMKR = Phone
-- OR [email protected] = Phone
UNION
-- LEFT JOIN COLLDEBT1@ ON [email protected] = [email protected]
SELECT MASTER FROM COLLDEBT1@ WHERE PHONE = Phone
-- OR [email protected] = Phone
UNION
-- LEFT JOIN U_SPOUSEINFO@ ON [email protected] = [email protected]
SELECT MASTERLINK FROM U_SPOUSEINFO@ WHERE SPOUSEPHN = Phone
-- OR [email protected] = Phone
UNION
-- LEFT JOIN U_ASTSCRN@ ON [email protected] = [email protected]
SELECT MASTERLINK
FROM U_ASTSCRN@
WHERE PHONE0 = Phone
OR PHONE1 = Phone
OR PHONE2 = Phone
OR PHONE3 = Phone
OR PHONE4 = Phone
OR PHONE5 = Phone
OR PHONE6 = Phone
OR PHONE7 = Phone
OR PHONE8 = Phone
OR PHONE9 = Phone
-- OR [email protected] = Phone
-- OR [email protected] = Phone
-- OR [email protected] = Phone
-- OR [email protected] = Phone
-- OR [email protected] = Phone
-- OR [email protected] = Phone
-- OR [email protected] = Phone
-- OR [email protected] = Phone
-- OR [email protected] = Phone
-- OR [email protected] = Phone
UNION
-- LEFT JOIN U_ASTSCRNB@ ON [email protected] = [email protected]
SELECT MASTERLINK
FROM U_ASTSCRNB@
WHERE PHONE10 = Phone
OR PHONE11 = Phone
OR PHONE12 = Phone
OR PHONE13 = Phone
OR PHONE14 = Phone
-- OR [email protected] = Phone
-- OR [email protected] = Phone
-- OR [email protected] = Phone
-- OR [email protected] = Phone
-- OR [email protected] = Phone
UNION
-- LEFT JOIN AUXDEBTOR@ ON [email protected] = [email protected]
SELECT DEBTORMASTER FROM AUXDEBTOR@ WHERE EMPLOYERPHONE = Phone
-- OR [email protected] = Phone
)
GROUP BY
MakerName
ORDER BY
MakerName
Кроме того, некоторую скорость можно получить, изменив подзапросы OR в списки IN; более поздние версии MySQL сделали некоторые оптимизации для них.